C++ dll 和名称修改问题
C++ dll and name mangling issue
我正在尝试一个简单的测试 DLL 项目。在我的解决方案下,我有两个项目——第一个 C++ Dll(库)和第二个 C++ exe(驱动程序)。下面我附上了基本项目设置的快照:
dllmain.h
#ifndef DLLMAIN_H_
#define DLLMAIN_H_
#ifdef FFMPEGLIB_EXPORTS
#define FFMPEGLIB_API __declspec(dllexport)
#else
#define FFMPEGLIB_API __declspec(dllimport)
#endif // FFMPEGLIB_EXPORTS
static void TestFoo();
extern "C" FFMPEGLIB_API void Test(int* num);
extern "C" FFMPEGLIB_API void ProxyFoo();
#endif
dllmain.cpp
#include "dllmain.h"
#include "A.h"
void TestFoo()
{
A a;
a.foo();
}
void Test(int* num)
{
*num = *num + 1;
}
void ProxyFoo()
{
TestFoo();
}
driver.cpp
#include <iostream>
#include "dllmain.h"
int main(int argc, char** argv)
{
int mum = 4;
Test(&num);
std::cout << num;
ProxyFoo();
return 0;
}
库项目编译正常,但exe编译失败,链接错误:
Code Description Project File
LNK2001 unresolved extern symbol _imp_ProxyFoo driver driver.obj
LNK2001 unresolved extern symbol _imp_Test driver driver.obj
LNK1120 2 unresolved externals driver driver.exe
我这里有两个问题:
为什么 dllmain.h
的函数名尽管被标记为 extern "C"
但还是被破坏了?
为什么我不能从 extern
方法创建测试 class A
的实例?这样做的好方法是什么?
您需要将 extern "C"
放在您打算在 dllmain.cpp
中导出的函数定义周围,以便它与您声明的链接相匹配。
此外,您还需要做 declexport
事情。
extern "C"
{
__declspec(dllexport) void Test(int* num)
{
*num = *num + 1;
}
__declspec(dllexport) void ProxyFoo()
{
TestFoo();
}
}
Why the function name of dllmain.h getting mangled in spite being
marked as extern "C"?
因为__declspec(dllimport)
.
Why can I not create instance of test class A from extern methods?
What would be good way of doing it?
我觉得没问题,但您没有提供任何 class A
代码。只需这样做:
class __declspec(dllexport) A
{
/* ... */
};
Why EXE compile failed?
这是因为你没有将DLL的LIB文件导入到项目中
有两种导入方式:
- 将
#program comment(lib, "<YOUR_LIB_FILE>.lib")
添加到代码文件。
- 将
<YOUR_LIB_FILE>.lib
添加到属性 -> 链接器 -> 输入 -> 附加依赖项。
微软文档:https://docs.microsoft.com/en-us/cpp/build/importing-and-exporting
我正在尝试一个简单的测试 DLL 项目。在我的解决方案下,我有两个项目——第一个 C++ Dll(库)和第二个 C++ exe(驱动程序)。下面我附上了基本项目设置的快照:
dllmain.h
#ifndef DLLMAIN_H_
#define DLLMAIN_H_
#ifdef FFMPEGLIB_EXPORTS
#define FFMPEGLIB_API __declspec(dllexport)
#else
#define FFMPEGLIB_API __declspec(dllimport)
#endif // FFMPEGLIB_EXPORTS
static void TestFoo();
extern "C" FFMPEGLIB_API void Test(int* num);
extern "C" FFMPEGLIB_API void ProxyFoo();
#endif
dllmain.cpp
#include "dllmain.h"
#include "A.h"
void TestFoo()
{
A a;
a.foo();
}
void Test(int* num)
{
*num = *num + 1;
}
void ProxyFoo()
{
TestFoo();
}
driver.cpp
#include <iostream>
#include "dllmain.h"
int main(int argc, char** argv)
{
int mum = 4;
Test(&num);
std::cout << num;
ProxyFoo();
return 0;
}
库项目编译正常,但exe编译失败,链接错误:
Code Description Project File
LNK2001 unresolved extern symbol _imp_ProxyFoo driver driver.obj
LNK2001 unresolved extern symbol _imp_Test driver driver.obj
LNK1120 2 unresolved externals driver driver.exe
我这里有两个问题:
为什么
dllmain.h
的函数名尽管被标记为extern "C"
但还是被破坏了?为什么我不能从
extern
方法创建测试 classA
的实例?这样做的好方法是什么?
您需要将 extern "C"
放在您打算在 dllmain.cpp
中导出的函数定义周围,以便它与您声明的链接相匹配。
此外,您还需要做 declexport
事情。
extern "C"
{
__declspec(dllexport) void Test(int* num)
{
*num = *num + 1;
}
__declspec(dllexport) void ProxyFoo()
{
TestFoo();
}
}
Why the function name of dllmain.h getting mangled in spite being marked as extern "C"?
因为__declspec(dllimport)
.
Why can I not create instance of test class A from extern methods? What would be good way of doing it?
我觉得没问题,但您没有提供任何 class A
代码。只需这样做:
class __declspec(dllexport) A
{
/* ... */
};
Why EXE compile failed?
这是因为你没有将DLL的LIB文件导入到项目中
有两种导入方式:
- 将
#program comment(lib, "<YOUR_LIB_FILE>.lib")
添加到代码文件。 - 将
<YOUR_LIB_FILE>.lib
添加到属性 -> 链接器 -> 输入 -> 附加依赖项。
微软文档:https://docs.microsoft.com/en-us/cpp/build/importing-and-exporting