Compile the DLL in C / C ++, then call it from another program

I want to create a simple, simple DLL that exports one or two functions, and then try to call it from another program ... Wherever I looked so far, these are complex things, different ways of connecting things, strange problems that I even didn't start to realize exist yet ... I just want to start by doing something like this:

Create a DLL that exports some functions, for example

int add2(int num){ return num + 2; } int mult(int num1, int num2){ int product; product = num1 * num2; return product; } 

I am compiling with MinGW, I would like to do it in C, but if there are any real differences in C ++, I would also like to know that. I want to know how to load this DLL into another C (and C ++) program, and then call these functions from it. My goal here, after playing around with the DLL a bit, is to make a VB interface for C (++) code by loading the DLLs in visual basic (I have visual studio 6, I just want to make some forms and events for objects on those forms, which cause the DLL).

I need to know how to call gcc (/ g ++) so that it creates a DLL, but also how to write (/ generate) an export file ... and what I can / cannot do in a DLL (for example, can I accept arguments a pointer / link from the front-end of VB? Can a DLL call a theoretical function in an interface? Or have a function-pointer function (I don’t even know if this is possible) from VB and name it?) I'm sure I can’t pass the option DLL ... but that's all I really know.

update again

Ok, I figured out how to compile it with gcc to run the DLL

 gcc -c -DBUILD_DLL dll.c gcc -shared -o mydll.dll dll.o -Wl,--out-implib,libmessage.a 

and then I had another program loading it and checking the functions, and it worked fine, Thanks a lot for the advice, but I tried downloading it using VB6, like this

 Public Declare Function add2 Lib "C:\c\dll\mydll.dll" (num As Integer) As Integer 

then I just called add2 (text1.text) from the form, but this gave me a runtime error:

"Cannot find add2 DLL entry point in C: \ c \ dll \ mydll.dll"

this is the code i compiled for the dll:

 #ifdef BUILD_DLL #define EXPORT __declspec(dllexport) #else #define EXPORT __declspec(dllimport) #endif EXPORT int __stdcall add2(int num){ return num + 2; } EXPORT int __stdcall mul(int num1, int num2){ return num1 * num2; } 

called it from C program, how it worked, though:

 #include<stdio.h> #include<windows.h> int main(){ HANDLE ldll; int (*add2)(int); int (*mul)(int,int); ldll = LoadLibrary("mydll.dll"); if(ldll>(void*)HINSTANCE_ERROR){ add2 = GetProcAddress(ldll, "add2"); mul = GetProcAddress(ldll, "mul"); printf("add2(3): %d\nmul(4,5): %d", add2(3), mul(4,5)); } else { printf("ERROR."); } } 

any ideas?

I decided

To solve the previous problem, I just had to compile it like this:

 gcc -c -DBUILD_DLL dll.c gcc -shared -o mydll.dll dll.o -Wl,--add-stdcall-alias 

and use this API call in VB6

 Public Declare Function add2 Lib "C:\c\dll\mydll" _ (ByVal num As Integer) As Integer 

I learned not to forget to explicitly specify ByVal or ByRef - I just returned the address of the argument that I passed, it looked like -3048.

+46
c ++ c gcc dll vb6
May 11 '09 at 9:41 a.m.
source share
5 answers

Regarding building a DLL using MinGW, here are some very short instructions.

First you need to mark your functions for export so that they can be used by calling DLLs. To do this, change them so that they look (for example)

 __declspec( dllexport ) int add2(int num){ return num + 2; } 

then if your functions are in the funcs.c file, you can compile them:

 gcc -shared -o mylib.dll funcs.c 

The -shared flag tells gcc to create a DLL.

To check if the DLL really exported functions, use the free Code :: Blocks tool, which works great with MinGW.

Edit: For more information, see the article Creating the MinGW Library for Use with Visual Basic on the MinGW Wiki.

+22
May 11 '09 at 10:28
source share

Here's how you do it:

In .h

 #ifdef BUILD_DLL #define EXPORT __declspec(dllexport) #else #define EXPORT __declspec(dllimport) #endif extern "C" // Only if you are using C++ rather than C { EXPORT int __stdcall add2(int num); EXPORT int __stdcall mult(int num1, int num2); } 

in .cpp

 extern "C" // Only if you are using C++ rather than C { EXPORT int __stdcall add2(int num) { return num + 2; } EXPORT int __stdcall mult(int num1, int num2) { int product; product = num1 * num2; return product; } } 

The macro tells your module (i.e. your .cpp files) that they provide dll material for the outside world. People who claim your .h file want to import the same features, so they sell EXPORT as they tell the linker to import. You need to add BUILD_DLL to the project compilation options, and you can rename it to something explicitly specific to your project (in case the dll uses your dll).

You may also need to create a file . def to rename functions and de-obfuscate names (C / C ++ manages these names) This blog entry can be an interesting starting point in this matter.

Downloading your own DLL files is similar to loading system DLL files. Just make sure the dll is on your system path. C: \ windows \ or the working directory of your application is a simple place to put your DLL.

+6
May 11 '09 at 10:30
source share

There is only one difference. You have to take care or call mangling win C ++. But on windows you need to take care of 1) defragment the functions that will be exported from the DLL 2) write the so-called .def file, which lists all the exported characters.

On Windows, when compiling a DLL, you must use

__ declspec (dllexport)

but when using it you should write __declspec (DllImport)

So the usual way to do this is something like

 #ifdef BUILD_DLL #define EXPORT __declspec(dllexport) #else #define EXPORT __declspec(dllimport) #endif 

Naming is a bit confusing because it is often called EXPORT. But this is what you will find in most headlines somewhere. So in your case you should write (with #define above)

int DLL_EXPORT add .... int DLL_EXPORT mult ...

Remember that when creating a shared library, you must add the Preprocessor BUILD_DLL directive.

Relations Friedrich

+5
May 11 '09 at 9:51 a.m.
source share

The thing to consider when writing C ++ libraries is called mangling. If you need interoperability between C and C ++, you would be better off exporting unsupported C-style functions from a DLL.

You have two options for using dll

  • Or use the lib file to refer to characters - dynamic time composition compilation
  • Use LoadLibrary() or some suitable function to load the library, get the function pointer ( GetProcAddress ) and call it - dynamic link-time execution

Exporting classes will not work if you follow the second method.

+4
May 11 '09 at 9:48 a.m.
source share

For VB6:

You need to declare your C functions as __stdcall, otherwise you will get errors like "invalid call". About your other questions:

Can I accept arguments with a pointer / link from a VB interface?

Yes, use ByRef / ByVal modifiers.

Can a DLL call a theoretical function in an interface?

Yes, use the AddressOf statement. You need to pass the function pointer to the dll before.

Or does the function have a “function pointer” (I don’t even know if this is possible) from VB and call it?)

Yes, use the AddressOf statement.

update (there were more questions)):

to load it into VB, I just do the usual method (what would I do to load winsock.ocx or some other runtime, but find my DLL instead), or am I putting an API call into a module?

You need the decaler API function in VB6 code, for example the following:

 Private Declare Function SHGetSpecialFolderLocation Lib "shell32" _ (ByVal hwndOwner As Long, _ ByVal nFolder As Long, _ ByRef pidl As Long) As Long 
+3
May 11 '09 at 10:01 a.m.
source share



All Articles