csharp-invoke c++ code

C++/CLI

貌似这个方法不推荐

WARNING
Other methods to create a .NET binding to a C# library exist. A notorious one is based on the compilation of the C++ library with the C++/CLI compiler. To keep things compatible with the Apple macOS, and because the IJW (it just works) technology sometimes does not, we suggest the use of PInvoke.

Platform Invoke (PInvoke)

allows .NET code to call functions that are implemented in a C/C++ DLL (Windows) or dylib (macOS).

pinvoke
P/Invoke Tutorial: Basics
Interop with Native Libraries

在 .NET 程序中使用 Win32 函数并不如 C++ 中方便。因为 C# 中不能引入 C++ 中常用的头文件,于是各种方法签名、结构体定义等等都需要各种寻找。然而 PInvoke.net 帮助我们解决了这个问题。本文推荐一款 Visual Studio 插件来帮助我们更快速地插入 Win32 函数签名。

在 Visual Studio 的“工具->扩展和更新”里面在线下载安装插件

参数类型

结构体指针

typedef struct nng_socket_s {
uint32_t id;
} nng_socket;

NNG_DECL int nng_pair0_open(nng_socket *);
[StructLayout(LayoutKind.Sequential)]
public struct nng_socket
{
public UInt32 id;
}

[DllImport(Import.nngLib, SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
static extern int nng_pair0_open(ref nng_socket socket);

const char *

NNG_DECL int nng_listen(nng_socket, const char *, nng_listener *, int);
[DllImport(Import.nngLib, SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int nng_listen(nng_socket socket, [MarshalAs(UnmanagedType.LPStr)] string url, nng_listener listener, int flag);

// 中文需要使用 CharSet.Unicode
[DllImport(Import.nngLib, SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
static extern int nng_send(nng_socket s, IntPtr buf, int len, int flags);

结构体 双重指针

//c++:结构体 **变量名   ----    c#:out 变量名   //C#中提前申明一个结构体实例化后的变量名

指针变量

int fnAdd(int *p_n1,int *p_n2);
[DllImport("你的dll名称", EntryPoint = "fnAdd", CallingConvention = CallingConvention.Cdecl)]
public static extern int fnAdd(ref int num1,ref int num2);

void*

void* a();
[DllImport("ddd.dll")]
public static System.IntPtr a();

byte[] to IntPtr

IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
// Call unmanaged code
Marshal.FreeHGlobal(unmanagedPointer);

double*

[DllImport(GageBoxMG4C2Lib, SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
static extern int GetAllChannelCurrentValue(double[] AValues, int ALen);

ref

http://ybeernet.blogspot.com/2011/03/techniques-of-calling-unmanaged-code.html

C++/CLI

貌似这个方法不推荐

WARNING
Other methods to create a .NET binding to a C# library exist. A notorious one is based on the compilation of the C++ library with the C++/CLI compiler. To keep things compatible with the Apple macOS, and because the IJW (it just works) technology sometimes does not, we suggest the use of PInvoke.