《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#外部调用的函数。
MyDLL.cpp里的代码如下:
extern "C" _declspec(dllexport)int add(int a ,int b)
{
int sum=a+b;
return sum;
}
注意:函数前一定要加
extern "C" _declspec(dllexport),
可被外部引用
项目->属性->常规->公共语言运行库支持->公共语言运行库支持(/clr)
F5编译程序,在Debug文件夹中找到生成MyDLL.dll目标文件备用
引用dll
新建项目->Visual C#->控制台应用程序 dllConsoleApplication1
将步骤1生成的MyDLL.dll文件copy到dllConsoleApplication1工程的根目录下
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);
}
}
}
编译程序,在程序中加断点,查看函数的计算结果
到这里,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++项目
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++的项目一定要选择公共语言运行时支持
在c#的项目中像引用c#的dll一样引用
代码中调用
Function fun = new Function();
int a = fun.menberFuncAdd(1, 2);
string s = fun.say("Hello World");
注意:c#项目一定要选择x86,否则要报错。
运行效果:
非托管
创建新的c++项目
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++的项目一定要选择公共语言运行时支持
在代码加上
[DllImport("ll.dll")]
public extern static void MessageBoxShow();
注意:c#项目一定要选择x86,否则要报错。
运行结果:
报错无法加载DLL,找不到指定模块
参考文档:cnblogs.com/yxzstruggle/p/16172138.html
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。