我有一个dll插件myDLL.cpp,它有以下代码:
#include "myDLL.h"
#include "MainApp.h"
class A{
public:
// NOTE: SomeType is defined in main application code.
A(SomeType* data) : m_data{data}
void MemberFunc(){
// NOTE: do_something should access data in main application.
m_data->do_something();
}
private:
SomeType* m_data;
};
// exported function
A* createInstance(SomeType* data){
return new A(data);
}
在我的主要应用程序中:
stc::vector<int> IntArray;
class SomeType{
SomeType(){
IntArray.resize(1000);
}
void do_something(){
// manipulate IntArray's contents.
IntArray[rand() % IntArray.size()] = rand();
}
};
typedef A*(_createInstance)(SomeType*);
void main(){
// Load the Dll and get createInstance()
_createInstance createInstance = LoadMyDLL();
SomeType someType;
A* a = createInstance(&someType);
a->MemberFunc();
// Free the instance of A and unload the DLL.
UnloadMyDLL(a);
}
dll代码现在可以使用主应用程序的API,但它无法访问正确的数据。当我在m_data->do_something();
处设置一个断点并输入方法调用时,我看到IntArray
为空。我做错了什么,如何解决问题?
答案 0 :(得分:1)
我可以成功运行您的示例而不会遇到您的问题:
do_something()
函数,它无法生成dll。正常,因为你的架构应该在应用程序中定义而不是在DLL中!我可以通过使do_something()
虚拟来解决问题。 MemberFunc()
和createInstance()
。我可以通过导出DLL条目来解决这个问题。 MemberFunc()
的麻烦,我也将其设为虚拟。 在上面的所有测试中,我完全没有问题。 IntArray
始终是正确的。在调试模式下,只要它进入范围,我就能看到预期的内容。
我的结论,从这些测试中看到你的片段(特别是doSomething不是虚拟的):你的问题可能是,它定义了带有函数的SomeType
类,最终{{1在IntArray
中。
如果是这种情况,你的DLL会引用它自己的这些元素的副本,而不是你想到的那些元素!这解释了为什么你没有看到预期值!
解决方案:
文件 MainApp.h :
Main.h
档案 MyDLL.h :
class SomeType{
public:
SomeType();
virtual void do_something();
};
档案 MyDLL.cpp :
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class A {
public:
A(SomeType* data);
virtual void MemberFunc(); // access through vtable. No need to link
private:
SomeType* m_data;
};
extern "C" { // use unmangled name for easo of use of dynamic loaded DLL
MYDLL_API A* createInstance(SomeType* data);
};
档案 main.cpp :
#define MYDLL_EXPORTS
#include "MainApp.h"
#include "MyDLL.h"
A::A(SomeType* data) : m_data{ data } {}
void A::MemberFunc(){ m_data->do_something(); }
extern "C" {
MYDLL_API A* cdecl createInstance(SomeType* data){ return new A(data); }
}