C++ 简单的dll编译提供C#调用#
非托管DLL:非.NET环境下编译而成的dll,无法通过添加引用的方式加入程序 托管DLL:在.NET环境下编译成的dll
会出现的问题 编译方面,注意函数名一定要前要加 extern "C"
,否则导出的dll函数名会有乱码符号导致调用时找不到函数入口
基本示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 \\vissim.h \\这是一个利用dll接入VISSIM的dll程序,包含了类,编写了几个函数接口来调用类 #ifdef VISSIMDLL_EXPORTS #define VISSIMDLL_API extern "C" __declspec(dllexport) #else #define VISSIMDLL_API __declspec(dllimport) #endif //引入VISSIM的COM接口 #import "C:\Program Files (x86)\PTV_Vision\VISSIM430\Exe\vissim.exe" using namespace VISSIM_COMSERVERLib; // 此类是从 vissimdll.dll 导出的 class Cvissimdll { private: ISimulationPtr _simulatiom; IVissimPtr _vissim; public: Cvissimdll(void); ~Cvissimdll(void); void VissimInit(); void VissimLoadNet(char*); void VissimRun(); }; VISSIMDLL_API void* VisClassInit(void **clsp); VISSIMDLL_API void OpenVissim(Cvissimdll *p); VISSIMDLL_API void LoadVissimNet(Cvissimdll *p,char* path); VISSIMDLL_API void ProRun(Cvissimdll *p);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 //vissimdll.cpp #include "stdafx.h" #include "vissimdll.h" Cvissimdll::Cvissimdll() { } Cvissimdll::~Cvissimdll() { } void Cvissimdll::VissimInit() { CoInitialize(NULL); _vissim.CreateInstance("Vissim.vissim"); MessageBox(NULL,"调用vissim成功!","调用提示",MB_OK); } void Cvissimdll::VissimLoadNet(char* path) { _vissim->LoadNet(path,false); MessageBox(NULL,"路网加载成功,运行仿真?","调用提示",MB_OKCANCEL); } void Cvissimdll::VissimRun() { _vissim->Simulation->RunContinuous(); } void* VisClassInit(void **clsp) { Cvissimdll* p = new Cvissimdll(); *clsp = p; return clsp; } void OpenVissim(Cvissimdll *p) { p->VissimInit(); } void LoadVissimNet(Cvissimdll *p,char* path) { p->VissimLoadNet(path); } void ProRun(Cvissimdll *p) { p->VissimRun(); }
C#的简单调用# 非托管dll的引用,在没有进行CLR的类封装编程时,只能调用dll中的函数,因此可以采用提供接口函数的方式来实现类的相关功能,如上面示例。采用的基本方法是P/invoke的方法调用。 首先需要添加引用using System.Runtime.InteropServices;
基本的调用方法参数 1 2 3 4 5 6 7 8 9 10 11 12 [AttributeUsage(AttributeTargets.Method)] public class DllImportAttribute: System.Attribute { public DllImportAttribute(string dllName) {…} //定位参数为dllName public CallingConvention CallingConvention; //入口点调用约定 public CharSet CharSet; //入口点采用的字符接 public string EntryPoint; //入口点名称 public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false public bool PreserveSig; //方法的签名是被保留还是被转换 public bool SetLastError; //FindLastError方法的返回值保存在这里 public string Value { get {…} } }
调用示例 使用上面C++编译的dll来实现VISSIM的调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 namespace vissimconn { public partial class Form1 : Form { [DllImport(@"E:\code\C++\vissimdll\Debug\vissimdll.dll", EntryPoint = "VisClassInit", CallingConvention = CallingConvention.Cdecl)] extern static int VisClassinit(ref int clapoint); [DllImport(@"E:\code\C++\vissimdll\Debug\vissimdll.dll", EntryPoint = "OpenVissim", CallingConvention = CallingConvention.Cdecl)] extern static void Openvissim(ref int clapoint); [DllImport(@"E:\code\C++\vissimdll\Debug\vissimdll.dll", EntryPoint = "LoadVissimNet", CallingConvention = CallingConvention.Cdecl)] extern static void LoadNet(ref int clapoint, string path); [DllImport(@"E:\code\C++\vissimdll\Debug\vissimdll.dll", EntryPoint = "ProRun", CallingConvention = CallingConvention.Cdecl)] extern static void Run(ref int clapoint); private int _clspoint = 0; private string path = @"C:\Users\jr-zsf\Desktop\黄山4.3\vissim.inp"; public Form1() { InitializeComponent(); _clspoint = VisClassinit(ref _clspoint); } private void button1_Click(object sender, EventArgs e) { Openvissim(ref _clspoint); label1.Text = "接口函数加载成功!"; } private void button2_Click(object sender, EventArgs e) { LoadNet(ref _clspoint, path); Run(ref _clspoint); label2.Text = "路网加载成功!"; } } }
最后补三张图 ![启动VISSIM][1] ![加载路网][2] ![启动仿真][3] [1]:http://flypigblog.oss-cn-beijing.aliyuncs.com/VISSIMC/1.PNG?x-oss-process=style/sy-highq [2]:http://flypigblog.oss-cn-beijing.aliyuncs.com/VISSIMC/2.PNG?x-oss-process=style/sy-highq [3]:http://flypigblog.oss-cn-beijing.aliyuncs.com/VISSIMC/3.PNG?x-oss-process=style/sy-highq