0%

c++ 编译dll 调用vissim

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