用VC++基于MFC动态链接库(dll)开发绘图组件,那么C#和VC++分别怎么使用dll?

一、VC DLL接口定义

以开发浮云绘图组件FYDC.dll为例,FYDC.dll是VC MFC动态链接库,有多个类库组成,其中包含MFC类和窗体、图标等资源。编码定义及过程如下:

1. 创建MFC常规动态链接库dll工程FYDC;

2. 实现CSLine画线、CSEllipse画圆等类,实现画布CCanvasWnd等所有绘图功能;

3. 在FYDC.h和FYDC.cpp添加绘图类库头文件,如CanvasWnd.h, SLine.h等;

4. 在FYDC.cpp定义导出接口(部分接口如下),并并实现。

1> extern "C" __declspec(dllexport) CCanvas* New()
2> extern "C" __declspec(dllexport) void Create(CCanvas* canvas, HWND hParentWnd, int x, int y, int w, int h)
3> extern "C" __declspec(dllexport) void Load(CCanvas* canvas, const char* fileName)4> extern "C" __declspec(dllexport) int GetCount(CCanvas* canvas)
5> extern "C" __declspec(dllexport) CSLine* GetAt(CCanvas* canvas, int index)
6> extern "C" __declspec(dllexport) void GetName(CSLine* line, wchar_t* name)7> extern "C" __declspec(dllexport) void GetSize(CCanvas* canvas, int& width, int& height)

5. 编译生成FYDC.dll和FYDC.lib,即完成dll开发,以供第三方工程复用。

二、C#使用dll详细步骤

1. 新建C#工程,复制FYDC.dll到生成的exe目录;

2. 在C#代码文件,添加FYDC.dll导入函数声明。与上面7个导出函数对应的C#版导入函数声明如下:

1> [DllImport("FYDC.dll", EntryPoint = "New", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr New();
2> [DllImport("FYDC.dll", EntryPoint = "Create", CallingConvention = CallingConvention.Cdecl)]
public static extern void Create(IntPtr canvas, IntPtr hParentWnd, int x, int y, int w, int h);
3> [DllImport("FYDC.dll", EntryPoint = "Load", CallingConvention = CallingConvention.Cdecl)]
public static extern void Load(IntPtr canvas, string fileName);4> [DllImport("FYDC.dll", EntryPoint = "GetCount", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetCount(IntPtr canvas);
5> [DllImport("FYDC.dll", EntryPoint = "GetAt", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GetAt(IntPtr canvas, int index);
6> [DllImport("FYDC.dll", EntryPoint = "GetName", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetName(IntPtr line, ref byte title);7> [DllImport("FYDC.dll", EntryPoint = "GetSize", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetSize(IntPtr canvas, ref int width, ref int height);

DLL导出函数类型                        对应                   C#导入函数类型

函数返回值 CCanvas*                                            函数返回值 IntPtr

函数形参 CSLine*                                                   函数形参 IntPtr

函数形参 HWND                                                     函数形参 IntPtr

函数形参 CShape**                                                函数形参 ref IntPtr

函数返回值或形参 int                                              函数返回值或形参 int

函数形参 &int                                                          函数形参 ref int

函数形参 const char*                                              函数形参 string

函数形参 char*                                                        函数形参 ref byte

注意:当函数dll形参时传出字符串时,字符串需要深拷贝,才能正确返回给C#

DLL返回字符串函数实现如下:

extern "C" __declspec(dllexport) void GetName(CSLine* line, char* name)
{if (shape != line){CString s = line->GetName();char attr[200];memset(attr, 0, sizeof(attr));memcpy(attr, s.GetBuffer(), s.GetLength());memcpy(name, attr, sizeof(attr));}
}

在C#项目中,正确使用该接口示例如下:

byte[] s = new byte[200];
lock (s)
{GetName(shape, ref s[0]);
}
string sName = System.Text.Encoding.Default.GetString(s, 0, s.Length);
sName = sName.Substring(0, sName.IndexOf('\0'));

当C#读取dll中文是乱码时,是因为双方编码约定未统一,此时应该:

① dll工程设置为多字节编码

②dll接口实现char*改成wchar_t*,并且调用MultiByteToWideChar函数转码

③C#导入函数形参不变,只需转码时Encoding.Default改成Encoding.Unicode

3. 在其他C#代码文件里直接引用此处的导出函数既可。

三、VC使用dll详细步骤

1. 新建VC++工程,复制FYDC.dll到生成的exe目录,并复制FYDC.lib到工程源码目录(不是exe目录);

2. 在VC代码文件,添加#pragma comment(lib,"FYDC.lib"),增加新类型导出声明,以及函数导出声明。与上面7个导出函数对应的C#版导入函数申明如下:

#pragma comment(lib,"FYDC.lib")
extern "C" __declspec(dllimport) class CCanvas;
extern "C" __declspec(dllimport) class CSLine;1> extern "C" __declspec(dllimport) CCanvas * New();
2> extern "C" __declspec(dllimport) void Create(CCanvas * canvas, HWND hParentWnd, int x, int y, int w, int h);
3> extern "C" __declspec(dllimport) void Load(CCanvas* canvas, const char* fileName);4> extern "C" __declspec(dllimport) int GetCount(CCanvas* canvas);
5> extern "C" __declspec(dllimport) CSLine* GetAt(CCanvas* canvas, int index);
7> extern "C" __declspec(dllimport) void GetName(CSLine* line, char* name);7> extern "C" __declspec(dllimport) void GetSize(CCanvas* canvas, int& width, int& height);

因为dll就是C++写的,那么VC工程引用的导出函数声明,是一样的。

3. 在VC代码文件直接调用已声明的dll的函数。

C#和VC++调用dll步骤,接口指针、字符串等类型对应关系相关推荐

  1. python如何调用dll库中的函数_Python调用dll库接口-ctypes方法

    背景 最近需要用python写个脚本程序(win10 环境),需要调用现成的dll库完成这项任务,对于一直在Linux平台上开发程序的本人来说,从没有过使用dll的经历(不得不说还是so大法好),遇到 ...

  2. C#调用VC的DLL的接口函数参数类型转换一览表

    handle---------IntPtr hwnd-----------IntPtr char *----------string int * -----------ref int int & ...

  3. VC调用Delphi对象接口

    说在前头 很久没有碰Delphi的东西了,今天有个朋友让我帮他将一个Delphi中已经实现的功能在VC中进行使用,虽然后来又用VC的方式实现了该功能,但是在实现过程中想到了这样的调用方式,特写下本文以 ...

  4. vc 调用dll函数报 0x0EEDFADE: (no name) 错误

    今天写个程序需要调用一个动态加载dll,写个测试程序一切正常. 集成到系统中就 报 0x0EEDFADE: (no name) 错误 经分析线程中调用.该方法访问了数据库.在线程开始处加上 CoIni ...

  5. qt/c++调用dll的方法实践

    qt/c++调用dll的方法实践 关于c++调用dll的方法,应该说是很成熟的,很多文章介绍的也很详细,可以直接套用. 这里不在详述其原理,而只是根据实际使用做一个实践总结. 主程序添加dll中的头文 ...

  6. java 如何调用dll_java调用dll方法总结

    常用的就是jni,jnative(基于jni封装了自己的jar包) 注意:java调用dll,必须dll里做了对应的处理.列如:方法名必须为_java_包名_类名_方法名 使用JNI调用dll步骤 新 ...

  7. java调用dll 指针参数_java调用c dll,指针参数和结构体参数搞定 | 学步园

    终于有了比较大的成果,不过身体也累完了,昨天又去打的吊瓶,坐成铁的时候差点就晕倒在里面了,不知道什么原因,抵抗力这么差,明天放假,要在家好好休息,今天早上碰到欢欢了,她说给我做好吃的,我愿意吃她做的糖 ...

  8. java调用dll 指针参数_java调用c dll,指针参数和结构体参数搞定

    终于有了比较大的成果,不过身体也累完了,昨天又去打的吊瓶,坐成铁的时候差点就晕倒在里面了,不知道什么原因,抵抗力这么差,明天放假,要在家好好休息,今天早上碰到欢欢了,她说给我做好吃的,我愿意吃她做的糖 ...

  9. VC调用MATLAB 产生的dll文件

    1.当然是先建立matlab的m文件. 我在matlab中定义了一个函数, 其m文件如下: function re=add(C) N=73;alpha=(0.2)*(pi/2); Ts=sqrt(2* ...

最新文章

  1. Linux运行Django项目远程访问时报错:Invalid HTTP_HOST header: '***.***.*.*:8000'.
  2. 装载服务器安装和配置_一站式解决方案
  3. Spring Boot学习总结(18)——Springboot 2.0选择HikariCP作为默认数据库连接池的五大理由
  4. php title 乱码,PHP发送UTF-8编码中文邮件标题乱码的解决
  5. 中文版边缘计算白皮书发布,引领行业新趋势
  6. mysql var目录很快_mysql的这些坑你踩过吗?快来看看怎么优化mysql
  7. 史上最全Java学习视频下载地址分享
  8. 【Dart语言第5篇】运算符
  9. 批量导出导入docker镜像
  10. 梯度向量的超简单理解
  11. 联想服务器忘记系统登录密码,联想路由器登陆密码忘记了怎么办
  12. AH快递单打印软件(顺丰申通圆通韵达中通天天EMS) 3.77
  13. Excel快捷键大全 Excel2013/2010/2007/2003常用快捷键大全【转】
  14. 如何删除“我的电脑”、“此电脑”中坚果云图标--三种方法(2020年的可行方案)
  15. Vue进阶(幺零三):Markdown 基本语法
  16. php修改头像怎么做,PHP - 点击更换头像
  17. windows10 录音机内录、外录、内外混合录的方法
  18. 2021.2.25课程摘要(逻辑教育-王劲胜)
  19. Expect 自动化控制和测试 Here Document 免交互 Linux- shell编程之免交互
  20. vue element 的 el-cascade 组件如何实现多选点击确认提交操作

热门文章

  1. 黑客Un Oracle注射笔记-知己知彼百战不殆
  2. OSChina 周三乱弹 ——所有树都绿了,却不知道谁干的!
  3. jmeter数据类型转换
  4. 本地VMware虚拟机能否取代阿里云主机
  5. 中文的停用词表,不用下载直接复制
  6. 经验分享丨如何准备三维视觉、SLAM相关职位的面试
  7. linux touch更新文件时间,linux 使用 touch 修改文件的修改时间
  8. python 在命令行中提示 indentationError:expected an indented block
  9. 删除一个字符串中所有出现的给定子字符串
  10. 面向对象:封装性、继承性、多态性总结