C# 与 C++ 互操作(C# 调用 C++ 的动态链接库)

方法1. 在c#中定义byte[], 交给c++操作

extern "C" __declspec(dllexport) void HelloWorld(char* name)
{
    name[0] = 'c';
}
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        static extern IntPtr LoadLibrary(string lpFileName);      
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);    
        [DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true, CharSet = CharSet.Ansi)]
        static extern bool FreeLibrary(IntPtr hModule);
        private delegate void DelegateHelloWorld(IntPtr a);

        private static void Main(string[] args)
        {
            IntPtr hModule = LoadLibrary(@"D:\MyProject\CSharp\CSharp\bin\Debug\Cplus.dll");
            IntPtr proc = GetProcAddress(hModule, "HelloWorld");

            Byte[] array = new Byte[100];
            array[0] = (byte)'a';
            array[1] = (byte)'b';
            array[2] = (byte)'c';
            IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            DelegateHelloWorld delegate1 = Marshal.GetDelegateForFunctionPointer(proc, typeof(DelegateHelloWorld)) as DelegateHelloWorld;

            delegate1(ptr);
            string str = Encoding.ASCII.GetString(array).Replace("\0", "");
            Console.WriteLine(str);
            Console.ReadLine();
        }
    }
}

方法2,定义结构体互传

参考文章:

https://blog.csdn.net/weixin_44029053/article/details/124622642

https://docs.microsoft.com/zh-cn/dotnet/framework/interop/interop-marshalling

方法3,使用char* 在c#和c++之间互传

extern "C" __declspec(dllexport) char* Test(char* p);

extern __declspec(dllexport) char* Test(char* p)
{
    string str = "123abc";
    const char* temp = str.c_str();
    char* dst = (char*)malloc(strlen(temp) + 1);
    if (dst == NULL)
    {
        return NULL;
    }
    strncpy(dst, temp, strlen(temp));
    dst[strlen(temp)] = '\0';
    return dst;
}
extern "C" __declspec(dllexport) void FreeMemory(char* p);
extern __declspec(dllexport) void FreeMemory(char* p)
{
    free(p);
}
{
    IntPtr pInfo = Test("321");
    string str = Marshal.PtrToStringAnsi(pInfo);
    FreeMemory(pInfo);
}


[DllImport("CPP.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Test(string s);

 

posted @ 2019-11-27 23:49  echo三毛  阅读(714)  评论(0编辑  收藏  举报