dll调用主程序函数的怪事!!!!!!!!!!!!!!!!!!!!!!!!!

guyue35 2013-11-05 02:33:35
想着跟同学一起开发,就想着同学写dll,我写exe,然后dll需要调用到exe中的函数。我查了下资料,说是通过回调函数实现的,自己测试了下,发下没问题。但是由于dll需要调用我的函数比较多,所以有网友建议把函数都写成类中,然后传入类指针实现,我试了下,代码如下。但是就发现出怪事了。

//1.dll文件
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
return TRUE;
}
class cla
{
public:
virtual void a();
virtual void b();
};

extern "C"
{
void __declspec(dllexport) Show(cla* AStruct)
{
AStruct->a();
AStruct->b();
};
}

////////////////1.exe文件
class cla
{
public:
virtual void a();
virtual void b();
};
void cla::a(){cout<<"本机cla::a"<<endl;}
void cla::b(){cout<<"本机cla::b"<<endl;}
void main()
{
HMODULE hmod=LoadLibrary("1.dll");
typedef void (*dll) (cla* AStruct);
dll fun=(dll)GetProcAddress(GetModuleHandle(NULL),"Show");
cla a;
fun(&a);
system("pause");
}


结果运行就出现错误——1.exe 中的 0x00000000 处有未经处理的异常: 0xC0000005: Access violation
代码中,我要说明下,我是vs2010+win8.1测试的,之所以dll的类中的函数要写成虚函数是因为如果我不加,程序就会报错——
(1.obj : error LNK2019: 无法解析的外部符号 "public: void __thiscall cla::b(void)" (?b@cla@@QAEXXZ),该符号在函数 _Show 中被引用
1>1.obj : error LNK2019: 无法解析的外部符号 "public: void __thiscall cla::a(void)" (?a@cla@@QAEXXZ),该符号在函数 _Show 中被引用)
,根本不能生成dll。只有加上virtual才顺利通过。
而错误Access violation,我的理解是程序可能是触发了window的内存保护机制,但是我查了资料,网上的让你就评论说这是空指针的原因,我就不懂了。。。究竟应该怎么修改才能让程序运行额?难道真的不能这样做吗????
...全文
186 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-11-07
  • 打赏
  • 举报
回复
你的处理方式,都是错误的,关键是thiscall 是种特殊的调用约定。 调用方式 是 a.f(); 对象,引用 p->f();指针
xspace_time 2013-11-07
  • 打赏
  • 举报
回复
查看纯虚类 虚类
Enter空格 2013-11-07
  • 打赏
  • 举报
回复
擦,真烂。。CSDN两个标签居然不能嵌套。
Enter空格 2013-11-07
  • 打赏
  • 举报
回复
目测,应该修改成这样。
dll fun=(dll)GetProcAddress(hmod,"Show");
另,你这个就是单纯的导出类。 隐约记得应该有关键字可以直接实现。 貌似用不到虚函数。
Enter空格 2013-11-07
  • 打赏
  • 举报
回复
目测,应该修改成这样。
dll fun=(dll)GetProcAddress(hmod,"Show");
另,你这个就是单纯的导出类。 隐约记得应该有关键字可以直接实现。 貌似用不到虚函数。
lunat 2013-11-05
  • 打赏
  • 举报
回复
符号cla要从dll中导出才行。
guyue35 2013-11-05
  • 打赏
  • 举报
回复
引用 3 楼 pink9527 的回复:
你那个程序就得用virtual
请问这是为什么要得加virtual呢??
xspace_time 2013-11-05
  • 打赏
  • 举报
回复
你那个程序就得用virtual
RabinSong 2013-11-05
  • 打赏
  • 举报
回复
dll fun=(dll)GetProcAddress(hmod,"Show"); if (fun != NULL) { cla a; fun(&a); }
赵4老师 2013-11-05
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧