怎样在DLL导出一个struct?

wendysen 2009-07-26 11:18:00
问题是这样。有一个DDL1,现在自己又做了一个DLL2,DLL中引用了DLL1的一个struct strXXXX。
在DLLCall中调用DLL2的函数以及类和结构,用到了结构strXXXX
那么请问,在DLL2中strXXXX应该怎么定义(引用)?如何导出呢?
...全文
1833 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
jufengaihaozhe 2009-07-29
  • 打赏
  • 举报
回复
DLL导出类
类和结构体大体相同

DLL中定义的类可以在应用工程中使用。

下面的例子里,我们在DLL中定义了point和circle两个类,并在应用工程中引用了它们(单击此处下载本工程)。

//文件名:point.h,point类的声明

#ifndef POINT_H

#define POINT_H

#ifdef DLL_FILE

class _declspec(dllexport) point //导出类point

#else

class _declspec(dllimport) point //导入类point

#endif

{

public:

float y;

float x;

point();

point(float x_coordinate, float y_coordinate);

};

#endif

//文件名:point.cpp,point类的实现

#ifndef DLL_FILE

#define DLL_FILE

#endif

#include "point.h"

//类point的缺省构造函数

point::point()

{

x = 0.0;

y = 0.0;

}

//类point的构造函数

point::point(float x_coordinate, float y_coordinate)

{

x = x_coordinate;

y = y_coordinate;

}

//文件名:circle.h,circle类的声明

#ifndef CIRCLE_H

#define CIRCLE_H

#include "point.h"

#ifdef DLL_FILE

class _declspec(dllexport)circle //导出类circle

#else

class _declspec(dllimport)circle //导入类circle

#endif

{

public:

void SetCentre(const point ¢rePoint);

void SetRadius(float r);

float GetGirth();

float GetArea();

circle();

private:

float radius;

point centre;

};

#endif

//文件名:circle.cpp,circle类的实现

#ifndef DLL_FILE

#define DLL_FILE

#endif

#include "circle.h"

#define PI 3.1415926

//circle类的构造函数

circle::circle()

{

centre = point(0, 0);

radius = 0;

}

//得到圆的面积

float circle::GetArea()

{

return PI *radius * radius;

}

//得到圆的周长

float circle::GetGirth()

{

return 2 *PI * radius;

}

//设置圆心坐标

void circle::SetCentre(const point ¢rePoint)

{

centre = centrePoint;

}

//设置圆的半径

void circle::SetRadius(float r)

{

radius = r;

}

类的引用:

#include "..\circle.h"//包含类声明头文件

#pragma comment(lib,"dllTest.lib");

int main(int argc, char *argv[])

{

circle c;

point p(2.0, 2.0);

c.SetCentre(p);

c.SetRadius(1.0);

printf("area:%f girth:%f", c.GetArea(), c.GetGirth());

return 0;

}

从上述源代码可以看出,由于在DLL的类实现代码中定义了宏DLL_FILE,故在DLL的实现中所包含的类声明实际上为:

class _declspec(dllexport) point //导出类point

{



}



class _declspec(dllexport) circle //导出类circle

{



}

而在应用工程中没有定义DLL_FILE,故其包含point.h和circle.h后引入的类声明为:

class _declspec(dllimport) point //导入类point

{



}



class _declspec(dllimport) circle //导入类circle

{



}

不错,正是通过DLL中的

class _declspec(dllexport) class_name //导出类circle

{



}

与应用程序中的

class _declspec(dllimport) class_name //导入类

{



}

匹对来完成类的导出和导入的!

我们往往通过在类的声明头文件中用一个宏来决定使其编译为class _declspec(dllexport) class_name还是class _declspec(dllimport) class_name版本,这样就不再需要两个头文件。本程序中使用的是:

#ifdef DLL_FILE

class _declspec(dllexport) class_name //导出类

#else

class _declspec(dllimport) class_name //导入类

#endif

实际上,在MFC DLL的讲解中,您将看到比这更简便的方法,而此处仅仅是为了说明_declspec(dllexport)与_declspec(dllimport)匹对的问题。

由此可见,应用工程中几乎可以看到DLL中的一切,包括函数、变量以及类,这就是DLL所要提供的强大能力。只要DLL释放这些接口,应用程序使用它就将如同使用本工程中的程序一样!
wendysen 2009-07-27
  • 打赏
  • 举报
回复
谢谢楼上的,好像是你说的那样哦,就是DLL2.h也得包含DLL1.h。
目前还没有发现其他问题,呵呵,多谢。
wendysen 2009-07-26
  • 打赏
  • 举报
回复
困难就是,我的strXXXX这个结构是在DLL1中定义的,我的DLL2重新封装了DLL1的函数,可是结构不知道怎么封装?
所以在DLLCall中包含DLL2.h和DLL2。lib时,因为用到了DLL1中的结构,就出错,不知道该怎么在DLL2中重新封装DLL1中的结构和导出!
arong1234 2009-07-26
  • 打赏
  • 举报
回复
你遇到什么错误了?

[Quote=引用 4 楼 wendysen 的回复:]
引用 3 楼 arong1234 的回复:
如果你结构没有定义成员函数和静态变量,只要放在头文件让别人包含即可,不需要导出


楼上的大侠可以详细一点吗/

但我的DLL2中  #include "DLL1.h"了
那DLLCall中只是包涵了DLL2头文件和库,但是为什么不能用DLL1中的strxxxx??
[/Quote]
wendysen 2009-07-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 arong1234 的回复:]
如果你结构没有定义成员函数和静态变量,只要放在头文件让别人包含即可,不需要导出
[/Quote]

楼上的大侠可以详细一点吗/

但我的DLL2中 #include "DLL1.h"了
那DLLCall中只是包涵了DLL2头文件和库,但是为什么不能用DLL1中的strxxxx??
arong1234 2009-07-26
  • 打赏
  • 举报
回复
如果你结构没有定义成员函数和静态变量,只要放在头文件让别人包含即可,不需要导出
oyljerry 2009-07-26
  • 打赏
  • 举报
回复
定义结构体,然后DLL中导出对应的方法get()等,然后把结构体作为get的参数等来传递对应的数据,你DLL中来获取。
可以把结构体放到一个公用的h文件中,所有的dll都可以引用它的定义
biweilun 2009-07-26
  • 打赏
  • 举报
回复
用接口导出,放出一些方法做接口调用
arong1234 2009-07-26
  • 打赏
  • 举报
回复
问题不在于dll2.cpp,而在于dll2.h
使用你dll2的人,一定会包含dll2.h吧?而dll2.h中引用了那个结构。在dll2中,由于你在dll2.cpp包含了dll1.h,因此不会出问题。而在使用dll2的exe工程中,你没有包含dll1.h,但是dll2.h又使用了dll1.h的结构,这个结构当然就成了未定义结构。所以你需要把dll2.h中所有对dll1中的类型的引用,才能不带dll1.h使用
[Quote=引用 17 楼 wendysen 的回复:]

我的DLL2.cpp中包含了DLL1.h,编译通过.
DLLCall工程中,如果不包含DLL1.h就报错,如果包含了DLL1.h就可以通过。

[/Quote]
wendysen 2009-07-26
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 arong1234 的回复:]
你说的非常不清楚!!你遇到的问题是“结构没有定义”,那么你就应该强调结构没有定义这个错误信息,但是你一直在问怎么导出结构,但是这个结构是不需要导出的,你的问题在严重误导别人。关注自己直接的问题,而不是漫无天际的创造一些问题来问。你应该直接贴出错误信息来询问,而不是在自己理解基础上问问题。如果你理解没有问题,恐怕就不需要问问题了。在一个有问题的理解的基础上问问题,很可能问的问题本身就完全错误。

C++是一个需要预先定义类型才能使用的语言,无论你逻辑上是怎么包装dll1的,只要你的dll2的头文件中引用了dll1定义的类型,但是你在dll2.h中没有定义dll1中的类型,并且也没有包含dll1.h,那当然要报类型找不到错误。

如果你完全不想把dll1.dll中的结构暴露给别人,你就需要确保你dll2的头文件中没有任何地方引用这个结构,否则要么你在dll2的头文件中重定义这个结构,要么包含dll1.h,这是显而易见的:引用的东西必须被定义

[/Quote]

我的DLL2.cpp中包含了DLL1.h,编译通过.
DLLCall工程中,如果不包含DLL1.h就报错,如果包含了DLL1.h就可以通过。

但是我并不理解为什么?

arong1234(阿荣)
还是要感谢你的批评!
IORI915189 2009-07-26
  • 打赏
  • 举报
回复
基础问题

自己用 自己定义的结构 自己还不清楚??
别人用 把结构定义给他 让他自己传递结构指针


arong1234 2009-07-26
  • 打赏
  • 举报
回复
我估计他不想把dll1的信息暴露给别人,这样他应该把dll2的头文件中所有和dll1有关的信息删除放到其他头文件中,而不是把dll1的信息放在他dll2头文件中,然后又不原意重定义dll1的类型,也不原意包含dll1的头文件。实际他还是不懂头文件的用处
[Quote=引用 13 楼 lsupper 的回复:]
不用导出啊,你定义个一样的就OK了~~~

或者你生成DLL的时候,的头文件拉过来就可以了~~~~
[/Quote]
arong1234 2009-07-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wendysen 的回复:]

唉, 上帝啊,不知道我说清楚没有。
[/Quote]
表述的人有义务让别人清楚自己的想法,坚持“我其实说的很清楚,其实是因为你水你傻才不懂”是没有意义的,很显然,即使你在喊上帝的时候,你的表述还是错误的,你还在问“怎么导出”
lsupper 2009-07-26
  • 打赏
  • 举报
回复
不用导出啊,你定义个一样的就OK了~~~

或者你生成DLL的时候,的头文件拉过来就可以了~~~~
arong1234 2009-07-26
  • 打赏
  • 举报
回复
你说的非常不清楚!!你遇到的问题是“结构没有定义”,那么你就应该强调结构没有定义这个错误信息,但是你一直在问怎么导出结构,但是这个结构是不需要导出的,你的问题在严重误导别人。关注自己直接的问题,而不是漫无天际的创造一些问题来问。你应该直接贴出错误信息来询问,而不是在自己理解基础上问问题。如果你理解没有问题,恐怕就不需要问问题了。在一个有问题的理解的基础上问问题,很可能问的问题本身就完全错误。

C++是一个需要预先定义类型才能使用的语言,无论你逻辑上是怎么包装dll1的,只要你的dll2的头文件中引用了dll1定义的类型,但是你在dll2.h中没有定义dll1中的类型,并且也没有包含dll1.h,那当然要报类型找不到错误。

如果你完全不想把dll1.dll中的结构暴露给别人,你就需要确保你dll2的头文件中没有任何地方引用这个结构,否则要么你在dll2的头文件中重定义这个结构,要么包含dll1.h,这是显而易见的:引用的东西必须被定义

[Quote=引用 10 楼 wendysen 的回复:]
我不是说了吗,错误就是“一些结构没有定义”
我不知道在哪里定义,怎么导出。
不过刚刚试了下,在DLLCall中,加入#include "DLL1.h"  居然不再报错,可我DLLCall使用的是DLL2,所以很不理解。
唉, 上帝啊,不知道我说清楚没有。
[/Quote]
wendysen 2009-07-26
  • 打赏
  • 举报
回复
再重申一下,我的DLL2完全是重新封装DLL1,就是DLL1中的结构不知道怎么处理(怎么封装怎么导出)?
我在一个工程师用DLL2的时候,用到了DLL1的结构,但DLL2中并没有做任何处理,可是加上了 #include "DLL1.h",就不再出现“结构没有定义”的错误了。
这样表述可明白呢?
wendysen 2009-07-26
  • 打赏
  • 举报
回复
我不是说了吗,错误就是“一些结构没有定义”
我不知道在哪里定义,怎么导出。
不过刚刚试了下,在DLLCall中,加入#include "DLL1.h" 居然不再报错,可我DLLCall使用的是DLL2,所以很不理解。
唉, 上帝啊,不知道我说清楚没有。
arong1234 2009-07-26
  • 打赏
  • 举报
回复
不正确表述你的问题,不回应别人问你的,只坚持不断问你的问题是不可能得到答案的。要学会和别人交流
[Quote=引用 6 楼 wendysen 的回复:]
困难就是,我的strXXXX这个结构是在DLL1中定义的,我的DLL2重新封装了DLL1的函数,可是结构不知道怎么封装?
所以在DLLCall中包含DLL2.h和DLL2。lib时,因为用到了DLL1中的结构,就出错,不知道该怎么在DLL2中重新封装DLL1中的结构和导出!
[/Quote]
arong1234 2009-07-26
  • 打赏
  • 举报
回复
你到底有没有定义结构的成员函数或者静态变量?!
你的错误到底是什么?
[Quote=引用 6 楼 wendysen 的回复:]
困难就是,我的strXXXX这个结构是在DLL1中定义的,我的DLL2重新封装了DLL1的函数,可是结构不知道怎么封装?
所以在DLLCall中包含DLL2.h和DLL2。lib时,因为用到了DLL1中的结构,就出错,不知道该怎么在DLL2中重新封装DLL1中的结构和导出!
[/Quote]

15,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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