c++、C#调用c++dll

可参考:在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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值