《dll篇》c#调用c++dll

c#调用c++dll

参考链接:https://jingyan.baidu.com/article/5d6edee2da72d699eadeecfe.html

生成dll

环境:VS2008

新建项目->Visual C++->Win32项目 MyDLL

注意:C++编写的dll一般是不能直接拿来C#调用,需要先新建个C++的工程把dll里的方法重新封装成可被C#外部调用的函数。

image

image

MyDLL.cpp里的代码如下:

extern "C"  _declspec(dllexport)int add(int a ,int b)

{

int sum=a+b;

return sum;

}

注意:函数前一定要加

extern "C"  _declspec(dllexport),

可被外部引用

项目->属性->常规->公共语言运行库支持->公共语言运行库支持(/clr)

image

F5编译程序,在Debug文件夹中找到生成MyDLL.dll目标文件备用

引用dll

新建项目->Visual C#->控制台应用程序 dllConsoleApplication1

image

将步骤1生成的MyDLL.dll文件copy到dllConsoleApplication1工程的根目录下

image

Program.cs代码如下

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;   //必须添加,不然DllImport报错

namespace dllConsoleApplication1

{

	class CPPDLL

	{

		[DllImport("MyDLL.dll", CharSet = CharSet.Ansi)] //引入dll,并设置字符集

		public static extern int add(int a ,int b);

	}

	class Program

	{

		static void Main(string[] args)

		{

			int sum=CPPDLL.add(3, 4);

		}

	}

}

编译程序,在程序中加断点,查看函数的计算结果

image

到这里,C++dll里的方法已经在C#里调用成功了。

如果你的C++dll里还调用了其他的dll文件那么需要把调用的其他dll文件也加到C#工程的根目录里,不然就会报错找不到MyDLL.dll模块。

c#调用c++dll法2

参考链接:https://www.jb51.net/article/247558.htm

介绍

C#是托管型代码,创建的对象会自动回收。C++是非托管型代码,创建的对象需要手动回收(有时不手动回收,可能出现内存溢出的问题)。

C#调用C++的方式分为两种:(1)采用托管的方式进行调用;(2)非托管的方式进行调用。

托管方式

采用托管的方式进行调用,就和正常调用c#的dll一样

创建新的c++项目

image

Function.h中的代码,一个返回两数之和的方法,一个返回字符串的方法

#pragma once
#include <string>
public ref class Function
{
public:
	Function(void);
	~Function(void);
	int menber;
	int menberFuncAdd(int a,int b);
	System::String^ say(System::String^ str);
};

//.cpp
#include "Function.h"
Function::Function(void)
{
}
Function::~Function(void)
{
}

int Function::menberFuncAdd(int a,int b)
{
   return a+b;
}
System::String^ Function::say(System::String^ str)
{
   return str;
}

Function.h中空白不用写

#include "Function.h"

注意:c++的项目一定要选择公共语言运行时支持

image

在c#的项目中像引用c#的dll一样引用

image

代码中调用

image

Function fun = new Function();
		   int a = fun.menberFuncAdd(1, 2);
		   string s = fun.say("Hello World");

注意:c#项目一定要选择x86,否则要报错。

image

运行效果:

image

非托管

创建新的c++项目

image

stdafx.h中的代码

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"
#ifdef A_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
#define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息
// Windows 头文件:
#include <windows.h>

extern "C" DLL_API void MessageBoxShow();

// TODO: 在此处引用程序需要的其他头文件

dllmain.cpp中的代码

#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
					   DWORD  ul_reason_for_call,
					   LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

#ifdef _MANAGED
#pragma managed(push, off)
#endif

void MessageBoxShow()
{
	MessageBox(NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}


#ifdef _MANAGED
#pragma managed(pop)
#endif

注意:c++的项目一定要选择公共语言运行时支持

image

在代码加上

[DllImport("ll.dll")]
 public extern static void MessageBoxShow();

image

注意:c#项目一定要选择x86,否则要报错。

image

运行结果:

image

报错无法加载DLL,找不到指定模块

参考文档:cnblogs.com/yxzstruggle/p/16172138.html

image

1.DLL文件夹放置位置:

(1)将缺少的DLL放到项目文件夹下的“/bin/bebug“

(2)系统文件夹下的”C:/WINDOWS/system32“

如果确定位置是正确的,那么就有可能是调用的DLL文件还用到了其他DLL文件中的内容,这很关键。可以通过下载Dependency Walker (depends.exe) Home Page查看缺少哪些dll库。

例如博主在调用C++封装的DLL时就报错,最后发现是需要安装C++运行环境,这个问题可通过安装”VC++ 运行库“来解决。

还有一种是在发布程序时,可能会缺少wpf的环境,例如”.NET Framework 4.6.1“只需要下载下来安装就可以了。

报错试图加载格式不正确的程序

参考链接:https://blog.csdn.net/songyi160/article/details/51354660

程序在32位操作系统上运行正常,在64位操作系统上运行读卡功能提示”试图加载格式不正确“。

出错原因:因为'任何 CPU'编译运行的程序在64位的机器上就会用运行为64位,而64位程序是不能加载32位dll的

解决方法:项目右键属性->项目设计器->生成->平台->把'默认设置(任何 CPU)'改为x86。

posted @ 2023-08-01 14:22  Fusio  阅读(997)  评论(0编辑  收藏  举报