如何将一个结构体从C++应用程序传递到C++ Win32 DLL?

3
如何在C++应用程序和C++ Win32 DLL之间传递结构体?能否给我一个例子?

你已经知道如何为你的DLL制作头文件,并从C++程序中调用DLL中的函数了吗? - David Grayson
是的,但我不确定传递结构体指针是否有问题。 - user1589684
2个回答

4
您可以传递指针,因为Windows中的DLL与程序在相同的地址空间中。
然而请注意,DLL接口止于此,您(通常)没有共享内存管理,并且通常不能传递例如std::vector并期望DLL能够push_back新元素。原因是DLL通常具有自己的内存管理器和堆,这些与调用者的内存管理器和堆分离(毕竟DLL可以从任何语言调用,不一定是C ++)。
即使可能会令人惊讶地传递一个std::map并且只是读取它,DLL也可能不起作用,因为标准库中的某些容器依赖于“哨兵”,并且这些哨兵也可能被复制到DLL。
在上述内容中,我使用了“通常”一词,因为DLL可能具有一些技巧,以便能够与主进程共享内存管理。例如,Microsoft MFC从VC6开始就被设计为在这些DLL屏障周围正常工作(但标准库不行!)。
您还必须确保DLL和主要程序使用完全相同的编译器和编译选项进行编译,否则即使是普通结构也可能具有不同的内存布局。

谢谢您的回复!如果我的dll将被广泛分发,那么我是否应该同时分发一个包含结构体的.h文件,这样任何语言的应用程序都可以传递dll结构体指针而不会出现任何问题? - user1589684
是的,您应该说明DLL期望的确切内存布局。更好的做法是除此之外还提供不同语言调用您的库的代码示例。 - 6502

1

你的struct是如何定义的?它是POD吗?还是一个简单的C struct?或者它是一个具有STL类实例成员的struct

如果这个struct是一个“纯C”struct,那么你可以直接将其传递给DLL。

但是,如果这个struct具有STL类作为数据成员,那么你必须确保.EXE和.DLL都使用动态链接到CRT,并且使用相同版本的Visual C++编译器相同类型的CRT进行构建(例如,如果你有一个调试版本的.EXE和一个发布版本的.DLL,则无法在边界处传递STL类,因为STL容器的实现从调试版本到发布版本会发生变化;如果你有一个使用VC10构建的.EXE和一个使用VC9构建的.DLL,则无法在边界处传递STL类)。

此外,您可能希望阅读CodeProject上有趣的文章: "如何从DLL导出C++类"

谢谢回复!我的结构体是纯C的,这对我来说是一个很好的学习例子。 - user1589684

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接