一 概述
C#开发过程中经常会用到C的库, 网上相关资料很多, 但不是很全, 所以将方法记录一下,以备以后查找
二 封装
C# 调用C的方法, 需要一个.cs文件,用以声明调用的 结构体和方法, 类似于c语言的头文件
1 定义命名空间
2 结构体声明
在结构体申明前 增加 [StructLayout(LayoutKind.Sequential)]
原因:C/C++中 默认情况下总是按照结构中占用空间最大的成员进行对齐(Align),因此c#声明是也应该要已此方式对齐
3 定义c#类
4 在类中声明对应的结构体
三 c# 和 c 类型对应
四 例子
1 c 头文件
#ifndef TRIANGE_H
#define TRIANGE_H
#ifdef _WIN32
#define SDK_API __declspec(dllexport)
#define STDCALL
#else
#define RS_SDK_API
#define STDCALL
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef void * handle;
typedef struct Point {
float x;
float y;
}Point;
typedef struct Triangle_name
{
char name[32];
}Triangle_name;
typedef struct Triange_extra
{
char* pData;
}Triange_extra;
typedef struct Triange
{
Point point_array[3];
Triangle_name name;
Triange_extra extra;
char uuid[64];
int sidenum;
}Triange;
SDK_API int STDCALL SetSrvaddr(const char* domain, int port);
SDK_API int STDCALL Login(user_t* user, handle* ph); // user 输入, ph 输出
SDK_API int STDCALL CreateTriange(handle ph, Triange * pTriange);
#ifdef __cplusplus
}
#endif
#endif //TRIANGE_H
2 c# 声明文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ManageApi
{
// float 类型
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public float x;
public float y;
};
// 数组类型
[StructLayout(LayoutKind.Sequential)]
public struct Triangle_name
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string name;
};
// 指针类型
[StructLayout(LayoutKind.Sequential)]
public struct Triange_extra
{
public IntPtr pData;
};
// 综合
StructLayout(LayoutKind.Sequential)]
public struct Triange
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public Point[] point_array;
public Triangle_name name;
public Triange_extra extra;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string uuid;
public int sidenum;
}
public class RSTriangeSDK
{
[DllImport("libTriangeC.dll", CallingConvention = CallingConvention.Cdecl)]
public extern static int SetSrvaddr(string domain, int port);
[DllImport("libTriangeC.dll", CallingConvention = CallingConvention.Cdecl)]
public extern static int Login(ref user_t user, out IntPtr handle);
[DllImport("libTriangeC.dll", CallingConvention = CallingConvention.Cdecl)]
int CreateTriange(IntPtr handle, ref Triange pTriange);
}
}