以下内容转自:http://blog.youkuaiyun.com/yysdsyl/article/details/2626033
前言:为了介绍C#写界面,C++写算法的快捷开发方式,C#与C++的交互,首先介绍c++,C#内部的DLL,COM调用。
一, 静态的Lib:静态的lib经过编译后只有.h和.lib文件,没有dll,因为实现部分也包含在lib中,这就是与动态dll的区别。还有在写静态lib的时候不需要在使用导出关键字_declspec(dllexport)。一般有2中方法调用静态lib,如下实例:
静态lib:CPPLib->test.h















静态lib的实现文件: CPPLib->test.cpp
























client调用CPPLibClient->CPPibClient.cpp



































调用方法:可以看出对于静态的只可以使用修改编译选项和pragma comment()来调用,不能使用loadlibrary()来调用。
二 ,动态DLL:在动态dll中,可以导出变量,函数和整个类。编译后有.h,.lib和dll文件,真正的实现包含在dll中,所以在client调用动态dll的时候,必须要使用dll,最后和client的放在同意目录下。要导出必须使用导出关键字_declspec(dllexport)。有时还使用extern “C”,为了使导出能够与C兼容,一般我们都加extern “c”。
一般调用有3中方法,实例如下:
实例1:演示了导出变量和函数,和前2中调用方法,修改编译选项和pragma comment().
动态dll:CPPdll->test.h








动态dll的实现:CPPDLL->test.cpp

























client的调用:cppclient->cppclient.cpp






























上面演示了对一般变量和函数的导出的调用方法中的其中的2中,修改编译选项和pragma comment(),当使用pragma comment()的使用,应当注意:
使用#pragma隐式加载动态库
对于变量,必须申明且不能include头文件。extern "C" _declspec(dllimport) int nCppDll;
对于函数,或include头文件,或是申明。extern "C" int fnCppDll(void);
对于类,最好使用函数封装导出指针供使用。
参考:http://www.cppblog.com/mzty/archive/2006/07/24/10419.html
实例2:演示类的导出和使用动态加载来调用。
动态dll的类导出:CPPDll2->test.h















动态dll的类导出的实现:CPPDll2->test.cpp








































对loadlibrary的分装,可以作为tools:

































client的调用:


















上面的是对类的动态调用,注意需要include头文件哦!
//通过API动态加载动态库
//对于类的导出,最好使用函数封装,导出类的指针。
//动态加载dll, 如果导出的函数只使用 extern,而没有使用extern "C" 则GetProcAdress会找不到函数的指针,要想找到可以使用真正要找的函数原型哦,可能是函数名后加@@。。。,也可以使用编号来找到需要的函数地址。
//但是如果导出函数使用extern "C"的话,导出函数的返回值不能是auto_ptr<>或shared_ptr<>哦,但是我们仍然可以使用智能指针哦,采用的方法是不使用return返回,使用函数的参数返回哦。//使用智能指针导出的更好的实现,请参考 http://www.cppblog.com/eXile
//参考: http://www.cppblog.com/eXile/archive/2007/04/19/22262.html
//更多dll类型:http://www.vckbase.com/document/viewdoc/?id=1116
//调用约定:http://blog.chinaunix.net/u/21790/showart_265932.html
三 资源DLL
在C++中,我们可以建立纯资源的动态dll,比如说我们建立了一个动态的资源dll,里面增加一个string: id为IDS_APPLICATION,值为:aaa,
则我们可以在client动态调用如下:















资源还可以是其他的比如是icon,bitmap。。。。等,有对应的load。()函数去调用。
四,总结
熟悉dll调用的3中方法,其中对静态的调用只有2中方法,一般对类的导出调用要使用函数封装哦!:~
以下内容转自:http://blog.youkuaiyun.com/yysdsyl/article/details/2626109
c++动态加载dll中的类(用于实现依据字符串类名创建对象)
参考资料:
http://blog.youkuaiyun.com/yysdsyl/archive/2008/07/08/2626033.aspx
用来生成dll的文件:
- ////////////////////////////Test.h
- class Test
- {
- public:
- Test(void);
- public:
- virtual ~Test(void);
- public:
- virtual void DoSth()=0;
- };
////////////////////////////Test.h
class Test
{
public:
Test(void);
public:
virtual ~Test(void);
public:
virtual void DoSth()=0;
};
--------------------------------------------
- ///////////////////TTest.h
- /////////////TTest继承自Test
- class TTest :
- public Test
- {
- public:
- TTest(void);
- public:
- ~TTest(void);
- public:
- virtual void DoSth(){std::cout<<"TTest:do sth/n";};
- };
///////////////////TTest.h
/////////////TTest继承自Test
class TTest :
public Test
{
public:
TTest(void);
public:
~TTest(void);
public:
virtual void DoSth(){std::cout<<"TTest:do sth/n";};
};
- ///////////关键
- extern "C" __declspec(dllexport) Test* CreateTTestPtr();
- extern "C" __declspec(dllexport) void DeleteTTestPtr(Test* t);
///////////关键
extern "C" __declspec(dllexport) Test* CreateTTestPtr();
extern "C" __declspec(dllexport) void DeleteTTestPtr(Test* t);
--------------------------------------------------
- ////////////////TTest.cpp
- #include "TTest.h"
- TTest::TTest(void)
- {
- }
- TTest::~TTest(void)
- {
- std::cout<<"destruct TTest/n";
- }
- Test* CreateTTestPtr()
- {
- return new TTest();
- }
- void DeleteTTestPtr(Test* t)
- {
- if(t!=NULL)
- delete t;
- }
////////////////TTest.cpp
#include "TTest.h"
TTest::TTest(void)
{
}
TTest::~TTest(void)
{
std::cout<<"destruct TTest/n";
}
Test* CreateTTestPtr()
{
return new TTest();
}
void DeleteTTestPtr(Test* t)
{
if(t!=NULL)
delete t;
}
- 测试程序:
测试程序:
- <pre class="csharp" name="code">#include "Test.h"
- #include <Windows.h>
- typedef Test* (CREATEFN)();
- typedef void (DELETEFN)(Test* );
- int _tmain(int argc, _TCHAR* argv[])
- {
- HINSTANCE hd=::LoadLibrary("AnotherDll.dll");
- CREATEFN* pfn;
- DELETEFN* xfn;
- pfn=(CREATEFN *)::GetProcAddress(hd,"CreateTTestPtr");
- xfn=(DELETEFN *)::GetProcAddress(hd,"DeleteTTestPtr");
- Test* t=(*pfn)();
- t->DoSth();
- (*xfn)(t);
- getchar();
- return 0;
- }
- </pre>
- <pre class="csharp" name="code"> </pre>
- <pre class="csharp" name="code"> </pre>
- <pre class="csharp" name="code"> </pre>
- <pre class="csharp" name="code">-------------------------------------------------------------------</pre>
- <pre class="csharp" name="code"> </pre>
- <pre class="csharp" name="code">向dll中添加新的继承于Test基类时,实现自身的同时实现下面的两函数</pre>
- <pre class="csharp" name="code">
- extern "C" __declspec(dllexport) Test* CreateXXXPtr();
- extern "C" __declspec(dllexport) void DeleteXXXPtr(Test* t);</pre>
- <pre class="csharp" name="code"> </pre>
- <pre class="csharp" name="code">(其中XXX表示新添加的类的类名,当然命名可以随意,只要你能在应用程序中找到这两导出函数,不过统一的命名规则</pre>
- <pre class="csharp" name="code">对根据类名创建对象是有好处的)</pre>