可参考:在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解)(已收藏)
- 一、生成C++ dll
(1)新建项目:win32 dll项目DynamicLinkLibrary,解决方案名:dllTest
(2)添加代码:
Add.h
#pragma once
//#define DLLEXPORT
//#define DLLIMPORT
#if defined(DLLEXPORT)
#define DLLAPI __declspec(dllexport)
#elif defined(DLLIMPORT)
#define DLLAPI __declspec(dllimport)
#endif
extern "C" DLLAPI int Add(int x, int y);// extern "C"很重要
Add.cpp
#include "Add.h"
extern "C" DLLAPI int Add(int x, int y)
{
return x + y;
}
(3)添加预定义DLLEXPORT(或者在Add.cpp开头中添加#define DLLEXPORT):
(4)编译生成。
- 二、C++调用dll
(1)添加空的win32控制台项目dllCall
(2)添加main.cpp文件:
//#include "..\DynamicLinkLibrary\Add.h"
#include <Windows.h>
#include <iostream>
int main()
{
typedef int(*pAdd)(int x, int y);//函数指针
HINSTANCE hHanlde;
hHanlde = LoadLibrary(L"DynamicLinkLibrary.dll");
if (hHanlde)
{
pAdd Add = (pAdd)GetProcAddress(hHanlde, "Add");
if (Add)
{
int value = Add(1, 2);
std::cout << value;
}
FreeLibrary(hHanlde);
}
return 0;
}
(3)编译生成,运行:
- 三、C#调用C++ dll
此处仅考虑调用C++ dll的函数,如果是C++的类则需要在c#中再定义相应的类。具体查看在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解)(已收藏),该文章的附加程序:CSharpInvokeCP代码.rar
(1)添加项目C#控制台项目dllCallCS;
(2)添加代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace dllCallCS
{
class Program
{
//可将DynamicLinkLibrary.dll复制到项目生成目录,再采用以下调用:
//[DllImport("DynamicLinkLibrary.dll")]
[DllImport(@"E:\VSproject\dllTest\Debug\DynamicLinkLibrary.dll")]
extern public static int Add(int x, int y);
static void Main(string[] args)
{
int v = Add(1, 2);
Console.WriteLine(v);
Console.ReadLine();
}
}
}
(3)在项目属性中,设置目标平台为x86(此处很重要,要保证与dll的平台一致,否则产生异常),可参考:试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
(4)编译生成,运行:
代码:dllTest.rar
- 四、C++调用dll的类
具体得另外调查,这里仅考虑简单的情况(可参考:怎样从一个DLL中导出一个C++类)。
dll代码与调用是同一编译器生成才有效;没有导出string类型(所以有警告,但调用端依然有效);或许可采用虚函数的实现形式。
(1)给DynamicLinkLibrary添加Person.h:
#pragma once
#if defined(DLLEXPORT)
#define DLLAPI __declspec(dllexport)
#elif defined(DLLIMPORT)
#define DLLAPI __declspec(dllimport)
#endif
#include <string>
using namespace std;
class DLLAPI Person
{
public:
Person(string name, int age) :_name(name), _age(age) {}
string _name;
int _age;
string PersonInfo();
};
添加Person.cpp:
#include "Person.h"
string Person::PersonInfo()
{
char ints[100];
memset(ints, 0, 100);
_itoa(_age, ints, 10);
string agestr = ints;
return string("名字:") + _name + string("\n") + string("年龄:") + agestr;
}
(2)编译生成,可用Dependency Walker(depends.exe)查看dll导出的函数:
因为不同编译器给成员函数命名(name mangling)不一样,所以调用端不能用其他编译器。
(3)调用端dllCall的main.cpp修改如下:
#include "..\DynamicLinkLibrary\Add.h"
#include "..\DynamicLinkLibrary\Person.h"
#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;
//#pragma comment(lib,"DynamicLinkLibrary.lib")//如果添加了库目录及附加依赖项,此项可注释
void CallClass()
{
Person person("张三", 20);
string info = person.PersonInfo();
cout << info.c_str();
}
int main()
{
//typedef int(*pAdd)(int x, int y);//函数指针
//HINSTANCE hHanlde;
//hHanlde = LoadLibrary(L"DynamicLinkLibrary.dll");
//if (hHanlde)
//{
// pAdd Add = (pAdd)GetProcAddress(hHanlde, "Add");
// if (Add)
// {
// int value = Add(1, 2);
// std::cout << value;
// }
// FreeLibrary(hHanlde);
//}
CallClass();
return 0;
}
注意添加库目录及附加依赖项
(4)编译生成,运行:
最终代码:dllTest-最终版.rar