C# 调用C++/MFC写的dll
C#调用C++的非托管类的dll其实很简单基本就是固定的调用格式.
dll的编写,首先是打开VS新建一个C++的控制台程序,下一步后选择dll以及空文档即可。然后就是添加一个类添加一个方法。方法排头固定格式 extern"C"__declspec(dllexport) 后面加方法即可。 例如如下代码:
C++dll代码:
extern "C" __declspec(dllexport) char* ShowImages(BYTE img[],int w,int h){;}
C#调用dll基本也是固定格式,如下样式,这边有添加unsafe这是因为有用到指针的缘故[没用指针不需要unsafe],C#用指针必须添加
unsafe,并且在项目属性里面的生成允许不安全代码打钩才行.
还有一点是C#调用DLL需要添加命名空间
using System.Runtime.InteropServices;
代码样式如下:
C#调用代码:
[DllImport("dll名字.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
unsafe public static extern byte* ShowImages(byte[] src, int w, int h);
按照如上编写dll以及调用失败原因多数可能就是C++的C#的数据类型没有对应的原因。
最后还有一点要提的是,具有指针返回值的方法,该指针变量在C++中必须是全局的,方法体里的私有的会出错。原因是出了方法体就被释放了,虽然是return出来的,也没有效果。
这个问题我之前就遇到过, C++里面return出来一个指针地址,然后C#里面调用,出来的数据乱七八糟,当时一直很郁闷,后来终于发现原因就是指针return出来还是会被释放掉,所以获得的数据乱七八糟。解决方法当然是把指针变量设成全局变量。
补充:[2014/01/16]
关于MFC编写DLL和C++写DLL是一样的;[以下是MFC规则DLL]
唯一不同点是在方法体最前添加一句话:AFX_MANAGE_STATE(AfxGetStaticModuleState());
如:
extern "C" __declspec(dllexport) void ShowImages()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());//MFC比普通的dll增加的内容(如何不涉及控件可以不加这句) //......
}
关于扩展DLL编写:
新建扩展DLL工程,添加类后,在类的开头修改 class AFX_EXT_CLASS CFormatBuilder : public CObject{;}
主要就是添加一个AFX_EXT_CLASS这样这个类就会作为DLL输出了。
C# 调用方法不变...
但MFC/Win32调用MFC/Win32的DLL有一些变化,方法如下:
1、显示调用:[MQXS.dll复制到运行目录下]
typedef void (*pFunction)(void);// 定义函数变量
::HINSTANCE hinstance = ::LoadLibraryW(_T("MQXS.dll"));
if (hinstance == NULL) MessageBox(_T("DLL加载失败"));
pFunction function = (pFunction)GetProcAddress(hinstance,"ShowImages");
function();
2、隐式调用:[规则DLL][MQXS.dll和MQXS.lib复制到运行目录下]
#include<stdio.h>
#pragma comment(lib,"MQXS.lib")
extern "C" _declspec(dllimport) void ShowImages();
ShowImages();//调用
3、隐式调用:[扩展DLL][MQXS.dll和MQXS.lib以及调用的类的头文件FormatBuilder.h复制到运行目录下]
#include "FormatBuilder.h"
#pragma comment(lib,"MQXSDLL.lib")
CFormatBuilder builder;//之后就可以使用该类的所有方法,全局变量了
补充:结构体传输定义
C++:
typedef struct Student
{
char name[];
int age;
double scores[];
}Student; extern "C" __declspec(dllexport) int GetStudent(Student stu);
C#:
[StructLayout(LayoutKind.Sequential)]
struct Student
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=)]
public string name;
public int age;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=)]
public double[] scores;
}
数组的传递:
C++:
extern "C" __declspec(dllexport) void SetData(int *data)
C#:
public static extern void SetData([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = )] ref int[] data);
C# 调用C++/MFC写的dll的更多相关文章
- java调用C/C++写的dll(转)
源:java调用C/C++写的dll Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台界面可以更快速,也能带来跨平台性. Java调用C/C++写好的DLL ...
- VS2017写的exe调用Delphi 7写的DLL
公司有个很古老的系统,代码量很大,并且稳定线上运行10几年,这系统是公司的核心,公司收入基本靠它,系统几乎都是Delphi 7写的,要重写是不可能的.因为Delphi 7编译出来的DLL默认的导出符号 ...
- c++ c# java 调用 c++ 写的dll
1. vs 中新建win32 dll 项目 testdll 添加实现文件 test.cpp #include "stdafx.h" #include <ios ...
- c++调用c#写的DLL
c++调用c#写的DLL: 此文章演示了建立c#的dll: c++建立工程,引入dll: 不能解决的问题: 指定dll的路径,在代码里面直接写 #using "xxx.dll" 必 ...
- QT调用C#写的Dll
参见: https://blog.csdn.net/weixin_42420155/article/details/81060945 C#写的dll是没有dllMain入口函数的,是一种中间语言,需要 ...
- Delphi7程序调用C#写的DLL解决办法(转)
近来,因工作需要,必须解决Delphi7写的主程序调用C#写的dll的问题.在网上一番搜索,又经过种种试验,最终证明有以下两种方法可行: 编写C#dll的方法都一样,首先在vs2005中创建一个 ...
- 发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象
发现个delphi调用vc写的Dll中包括pchar參数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会执行报错,在之前随意加上条语句就不报错了奇怪! vc的DLL源代码地址 ...
- 【转载】java调用C++写的DLL
用java调用C++写的DLL一直以来都是一个比较麻烦但又很常见的问题. 我们知道,使用 JNI 调用 .dll/.so 共享类库是非常非常麻烦和痛苦的. 如果有一个现有的 .dll/.so 文件,如 ...
- Delphi7程序调用C#写的DLL解决办法
近来,因工作需要,必须解决Delphi7写的主程序调用C#写的dll的问题.在网上一番搜索,又经过种种试验,最终证明有以下两种方法可行: 编写C#dll的方法都一样,首先在vs2005中创建一 ...
随机推荐
- MacBook Air 使用技巧
1.Finder 相当于资源管理器 Launchpad 相当于桌面 Safari 浏览器 2.快捷键 * cmd+shift+3: 捕获整 ...
- 【读书笔记】iOS-GCD-使用方法
代码: -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { dispatch_async(dispatch_get_gl ...
- Spring(一)简述
一.Spring简述 一段费话 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2 ...
- Android源码分析之Looper
先来说说summary,Looper就是用来在某个线程中跑一个message loop.一个线程默认是没有message loop与之相关联的, 为了创建一个你必须在这个线程中调用Looper.pre ...
- OC语言-08-深拷贝与浅拷贝详解(示例)
概述 拷贝:复制一个与源对象内容相同的对象 实现拷贝,需要遵守以下两个协议 NSCopying NSMutableCopying 拷贝返回对象的种类 可变,mutableCopy消息返回的对象 不可变 ...
- iOS支付宝集成时遇到的问题整理(2)
1.集成支付宝SDK编译报错#include<openssl/asn1.h>这一行 “openssl/asn1.h”file not found 解决方法:在BuildSetting 里 ...
- 搭建openvpn 未完成。。。
轻松构建自己的OpenVPN家庭服务器(VMware+Amahi) http://os.51cto.com/art/201107/277146_all.htm 这是教程 不用安装第一步的,直接把下载 ...
- Sql server存储过程中常见游标循环用法
用游标,和WHILE可以遍历您的查询中的每一条记录并将要求的字段传给变量进行相应的处理 DECLARE ), ), @A3 INT DECLARE YOUCURNAME CURSOR FOR SELE ...
- http://runjs.cn/
http://runjs.cn/ RunJS - 在线编辑.展示.分享.交流你的 JavaScript 代码
- 【mysql】添加对emoji的支持
1.简介 涉及无线相关的 MySQL 数据库建议都提前采用 utf8mb4 字符集,避免 emoji 表情符号带来的问题 MySQL Server > 5.5.3 2.配置+升级 当前配置 m ...