C ++:显式DLL加载:非“extern C”的第一次机会异常功能 [英] C++: Explicit DLL Loading: First-chance Exception on non "extern C" functions
问题描述
第一次机会cpp.exe中的0x00000000异常:0xC0000005:访问冲突。
DLL.h:
externC__declspec(dllimport)int addC(int a,int b);
__declspec(dllimport)int addCpp(int a,int b);
DLL.cpp:
#includeDLL.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\\\
,a,b);
printf(pfnAddC:%d\\\
,pfnAddC(a,b));
printf(pfnAddCpp:%d\\\
,pfnAddCpp(a,b)); // EXCEPTION ON this LINE
}
getchar();
return 0;
}
如何导入c ++函数以进行动态加载?我发现以下代码通过引用* .lib来处理隐式加载,但我想了解动态加载。
提前谢谢。
更新:
bindump / exports
code> 1 00011109?addCpp @@ YAHHH @ Z = @ ILT + 260(?addCpp @@ YAHHH @ Z)
2 00011136 addC = @ ILT + 305(_addC)
解决方案:
- 创建转换结构
found 这里 -
查看
文件导出并显式复制
c ++ mangle命名约定
PFNaddCpp pfnAddCpp =(PFNaddCpp)GetProcAddress(hDLL,?addCpp @@ YAHHH @ Z);
不可避免地,空指针上的访问冲突是beca使用 GetProcAddress()
返回null错误。
解决这个问题的一个选项是使用 .def 文件导出功能重命名导出的函数。有一篇文章,显式链接到DLL中的类 ,描述需要做什么。
I am having trouble importing my C++ functions. If I declare them as C functions I can successfully import them. When explicit loading, if any of the functions are missing the extern as C decoration I get a 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 can I import c++ functions for dynamic loading? I have found that the following code works with implicit loading by referencing the *.lib, but I would like to learn about dynamic loading.
Thank you to all in advance.
Update: bindump /exports
1 00011109 ?addCpp@@YAHHH@Z = @ILT+260(?addCpp@@YAHHH@Z)
2 00011136 addC = @ILT+305(_addC)
Solution:
- Create a conversion struct as found here
Take a look at the file exports and copy explicitly the c++ mangle naming convention.
PFNaddCpp pfnAddCpp = (PFNaddCpp)GetProcAddress(hDLL, "?addCpp@@YAHHH@Z");
Inevitably, the access violation on the null pointer is because GetProcAddress()
returns null on error.
The problem is that C++ names are mangled by the compiler to accommodate a variety of C++ features (namespaces, classes, and overloading, among other things). So, your function addCpp()
is not really named addCpp()
in the resulting library. When you declare the function with extern "C"
, you give up overloading and the option of putting the function in a namespace, but in return you get a function whose name is not mangled, and which you can call from C code (which doesn't know anything about name mangling.)
One option to get around this is to export the functions using a .def file to rename the exported functions. There's an article, Explicitly Linking to Classes in DLLs, that describes what is necessary to do this.
这篇关于C ++:显式DLL加载:非“extern C”的第一次机会异常功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!