C ++: Explicit DLL loading: exception from the first chance for functions without the "extern C" function

I am having problems importing my C ++ functions. If I declare them as C functions, I can import them successfully. When explicitly loading, if any of the functions is missing, extern, as a decoration for C, I get the following exception:

First-chance exception at 0x00000000 in cpp.exe: 0xC0000005: Access violation. 

DLL.h:

 extern "C" __declspec(dllimport) int addC(int a, int b); __declspec(dllimport) int addCpp(int a, int b); 

DLL.cpp:

 #include "DLL.h" int addC(int a, int b) { return a + b; } int addCpp(int a, int b) { return a + b; } 

main.cpp:

 #include "..DLL/DLL.h" #include <stdio.h> #include <windows.h> int main() { int a = 2; int b = 1; typedef int (*PFNaddC)(int,int); typedef int (*PFNaddCpp)(int,int); HMODULE hDLL = LoadLibrary(TEXT("../Debug/DLL.dll")); if (hDLL != NULL) { PFNaddC pfnAddC = (PFNaddC)GetProcAddress(hDLL, "addC"); PFNaddCpp pfnAddCpp = (PFNaddCpp)GetProcAddress(hDLL, "addCpp"); printf("a=%d, b=%d\n", a,b); printf("pfnAddC: %d\n", pfnAddC(a,b)); printf("pfnAddCpp: %d\n", pfnAddCpp(a,b)); //EXCEPTION ON THIS LINE } getchar(); return 0; } 

How to import C ++ functions for dynamic loading? I found that the following code works with implicit loading, referencing * .lib, but I would like to know about dynamic loading.

Thanks to everyone in advance.

Update: bindump / exports

 1 00011109 ?addCpp@ @ YAHHH@Z = @ILT+260( ?addCpp@ @ YAHHH@Z ) 2 00011136 addC = @ILT+305(_addC) 

Decision

  • Create the transformation structure as found here
  • Take a look at the file exports and copies the c ++ mangle naming convention.

    PFNaddCpp pfnAddCpp = (PFNaddCpp) GetProcAddress (hDLL, "? AddCpp @@ YAHHH @Z");

0
source share
2 answers

Inevitably, an access violation on a null pointer is due to GetProcAddress() returning null on error.

The problem is that C ++ names are crippled by the compiler to accommodate many C ++ functions (namespaces, classes and overloads, among other things). So your addCpp() function is not really called addCpp() in the resulting library. When you declare a function using extern "C" , you refuse the overload and the ability to put the function in the namespace, but in return you get a function whose name is not distorted and which you can call from C code (which does not work) t know what- anything about a mangling name.)

One way around this is to export functions using a .def file to rename the exported functions. It describes the article Explicit Class Binding in a DLL that describes what is needed for this.

+1
source

You can simply wrap the entire header file in extern "C" as follows. Then you don’t have to worry about forgetting extern "C" in one of your ads.

 #ifdef __cplusplus extern "C" { #endif __declspec(dllimport) int addC(int a, int b); __declspec(dllimport) int addCpp(int a, int b); #ifdef __cplusplus } /* extern "C" */ #endif 

You can still use all the C ++ functions that you are used to in function bodies β€” these functions are still C ++ functions β€” they just have prototype restrictions to make them compatible with C code.

0
source

All Articles