C++侧,编译为原生dll
#include <iostream>
#include "Windows.h"
#include "strsafe.h"
#define EXPORT_SYMBOL __declspec(dllexport)
extern "C" {
/*
* 纯函数C#引用示例
*
[DllImport("CPP")]
public static extern void PureFunction();
*/
EXPORT_SYMBOL void PureFunction();
/*
* 如果要定制在C#中返回string的非托管函数,有以下要点:
* - 返回char*
* - 返回的char*所指内存必须由COM任务内存分配器分配(例如使用CoTaskMemAlloc),之后C++层无需考虑释放此内存。这是因为C#层面在封送数据时会自动调用CoTaskMemFree释放它
* (注: 用默认方式分配的C字符串,例如new或malloc,无法在C#层面正确释放,包括Marshal.FreeHGlobal,因此DLL必须一并提供释放函数。对于这种情况,C#层需要把函数返回类型设置为IntPtr)
*/
EXPORT_SYMBOL char* ReturnNewString();
}
void PureFunction()
{
std::cout << "C++\n";
}
char* ReturnNewString()
{
const size_t alloc_size = 64;
char* result = (char*) CoTaskMemAlloc(alloc_size);
if (!result)
{
return nullptr;
}
char teststr[] = "Return string from C++";
memcpy(result, teststr, sizeof(teststr));
return (char*)result;
}
C#侧,导入dll并调用
using System;
using System.Runtime.InteropServices;
namespace CSharp
{
internal class Program
{
[DllImport("CPP_dll_name")]
public static extern void PureFunction();
[DllImport("CPP_dll_name")]
public static extern string ReturnNewString();
static void Main(string[] args)
{
Console.WriteLine("Hello From C#!");
PureFunction();
for (int i = 0; i < 1000000; ++i)
{
var str = ReturnNewString();
Console.WriteLine($"{i} {str}");
}
Console.ReadKey();
}
}
}
更多的示例,参见微软官方文档:从托管代码调用本机函数 | Microsoft Learn