#ifdef FOODLL_EXPORTS #define FOO_API __declspec( dllexport ) #else #define FOO_API __declspec( dllimport )
我的目的是在我的DLL实现以及控制台应用程序中使用此标头.到目前为止,导入和导出功能工作正常.当我尝试导出一个已经定义的结构作为其中一个导出函数的参数时,问题就出现了.例如,在前面提到的头文件中,我声明了FOO_API void foo(FooParams * args),而args是一个定义如下的结构:
typedef struct FooParams { char *a; char *b; void *whatever; //some other type } FooParams;
此结构必须在foo.h中定义,而不是在fooExports.h中定义.是否有任何方法可以导出此结构而不将其从原始头文件中删除(考虑到我希望将导出/导入集中在fooExports.h中).
这样做会有什么更好的方法? DLL都是C以及使用它的客户端应用程序.
typedef struct FooParams FooParams;
在fooExports.h中. FOO_API宏不属于该声明. opaque类型意味着客户端代码不能:
>创建FooParams类型的任何变量(但是FooParams * ptr = NULL;没关系).
>对FooParams的任何成员做任何事情.
>查找sizeof(FooParams) – 因此无法正确地为一个或多个FooParams对象提供malloc空间.
您也不能#define对客户端可见的宏执行上述任何操作.所以你的DLL需要有一个或多个“构造函数”或“工厂”函数,可能就像
FOO_API FooParams* CreateFooParams(const char * input);
FOO_API void DestroyFooParams(FooParams * p);
即使定义像{free(p);因为如果在DLL内部分配的内存被外部的代码释放,反之亦然(因为并非所有的Windows代码都使用相同的malloc和free定义),因此有时会出现问题.
如果所有这些都太极端,唯一的另一个选择是在导出的头文件中放入或#include结构定义,并使其对客户端可见.没有它,除了传递指针之外,任何对FooParams做某事的尝试都是不可能的,因为编译器不会知道FooParams中的内容.编译器(与链接器相对)仅从命令行参数和#include-d文件获取信息,而不是从库或DLL获取信息.