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中创建一 ...
随机推荐
- iOS Block(一)
Block使用总结: 1.格式: ReturnType (^ BlockName)(参数…); //例: int (^ BFunc) (int a, int b); 2.block赋值: block名 ...
- oc语言常用的字符串函数
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { ...
- ERROR: The partition with /var/lib/mysql is too full! failed!
发现:ERROR: The partition with /var/lib/mysql is too full! failed! 然后df -h 发现硬盘100% 于是分析到底什么占用了这近两百G ...
- C#输入输出重定向
当 Process 将文本写入其标准流中时,通常将在控制台上显示该文本.通过重定向 StandardOutput 流,可以操作或取消进程的输出.例如,可以筛选文本.用不同方式将其格式化,也可以将输出同 ...
- docker-1 初识docker
五分钟认识docker 什么是docker? 把他想象成一个用了一种新颖方式实现的超轻量虚拟机,在大概效果上也是正确的.当然在实现的原理和应用上还是和VM有巨大差别的,并且专业的叫法是应用容器(App ...
- 问题解决——在结构体中使用set保存结构体数据
=====================声明========================== 本文原创,转载请明确的注明出处和作者,并保持文章的完整性(包括本声明部分). 本文链接:http:/ ...
- HDU 4050 wolf5x(动态规划-概率DP)
wolf5x Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HttpClent4.3 的例子
package com.unbank.robotspider.util; import java.io.IOException; import java.net.MalformedURLExcepti ...
- jsp页面img利用tomcat配置访问服务器绝对路径显示图片
1.打开tomcat下的server.xml文件,路径\apache-tomcat-7.0.62\conf文件夹下. 2.下<host></host>加入<Context ...
- Error && MFC
Error:MSB6006 "rc.exe" exited with code 2. 目录含有中文 Error:no instance of overloaded function ...