C#调用C或C++编写的DLL库
1.编写DLL文件
(1)新建DLL工程
(2)选择空工程,类型为DLL
(3)添加.c文件
#include <stdio.h>
struct struStudent
{
int a;
int b;
int c;
};
extern "C" __declspec(dllexport) int add(struStudent strStudent,int b);
int add(struStudent strStudent,int b)
{
return (strStudent.a)+b;
}
(4)点击编译按钮,生成DLL文件
2.用C#调用生成的DLL文件
(1)新建一个C#的WinForm程序,将DLL文件同时拷入到Debug和Release目录下,Debug模式一般是在调试阶段经常使用的,Release模式一般是生成最后的成品,包含了软件所需要的环境。
界面如下:
(2)添加环境变量
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//import DLL use
using System.Runtime.InteropServices;
(3)编写DLL的函数声明
[DllImport("testDLL.dll", EntryPoint = "add", CallingConvention = CallingConvention.Cdecl)]
public static extern int add(struStudent strStudent, int b);
拓展:
[DllImport(@"patterns.dll", EntryPoint = "lbp_load_model", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
extern static int lbp_load_model(IntPtr path);
lbp_load_model(Marshal.StringToHGlobalAnsi(train_result));
(4)相关变量
int c = 88;
//定义枚举类型的变量
public enum enum_a : int
{
DN_125K = 0,
DN_250K = 1,
DN_500K = 2
}
//定义普通类型的Struct
//Marshal就是把一个结构(类)序列化成一段内存,然后送到另一个进程(.net中Application domain)中供另一个进程 中的函数使用。
[StructLayout(LayoutKind.Sequential)]
public struct struStudent
{
[MarshalAs(UnmanagedType.U4)]
public enum_a a;
public int b;
public int c;
}
拓展:
//如果定义一个共用体
[StructLayout(LayoutKind.Explicit)]
struct S1
{
[MarshalAs(UnmanagedType.U4)]
public enum_a a;
[FieldOffset(4)]
int b;
[FieldOffset(4)] //b和c在内存中地址相同。
int c;
}
(5)响应函数
Boolean ClearStruct(out struStudent stru)
{
stru.a = enum_a.DN_500K;
stru.b = 25;
stru.c = 3366;
return true;
}
private void button1_Click(object sender, EventArgs e)
{
int c;
struStudent struA;
struA.a = enum_a.DN_125K | enum_a.DN_250K;
struA.b = 0;
struA.c = 20;
c = add(struA, 88);
MessageBox.Show(Convert.ToString(add(struA, 88)));
// MessageBox.Show(c.ToString("X"));
struStudent struB;
ClearStruct(out struB);
MessageBox.Show((struB.b).ToString());
}
结果: