首先,我會調整你的本地函數的原型。
由於此函數具有C接口,因此您應該使用C類型作爲布爾值,而不是C++類型,如bool
。您可能想要使用Win32的BOOL
類型。
而且,因爲它是目前,你的作用是容易緩衝區溢出:最好是添加另一個參數指定目的地result
字符串緩衝區的最大尺寸。
還要注意的是普遍調用的DLL導出純C接口函數慣例(如大量的Win32 API函數)是__stdcall
(不__cdecl
)。我也會使用它。
最後,由於前兩個參數是輸入字符串,您可能希望使用const
來清除並強制執行const正確性。
所以,我會做導出的原生功能,這樣的原型:
extern "C" __declspec(dllexport)
BOOL __stdcall NativeFunction(
const char *in1,
const char *in2,
char *result,
int resultMaxSize);
然後,在C#的一面,你可以使用下面的P/Invoke:
[DllImport(
"NativeDll.dll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool NativeFunction(
string in1,
string in2,
StringBuilder result,
int resultMaxSize);
請注意,對於輸出字符串,使用StringBuilder
。
還要注意CharSet = CharSet.Ansi
用於編組的C#的Unicode UTF-16字符串ANSI(注意一個事實,即轉換爲有損 - 如果你想要一個無損轉換,只需使用在C wchar_t*
串++方面也是如此)。
我做了一個簡單的C測試++本地DLL:
// NativeDll.cpp
#include <string.h>
#include <windows.h>
extern "C" __declspec(dllexport)
BOOL __stdcall NativeFunction(
const char *in1,
const char *in2,
char *result,
int resultMaxSize)
{
// Parameter check
if (in1 == nullptr
|| in2 == nullptr
|| result == nullptr
|| resultMaxSize <= 0)
return FALSE;
// result = in1 + in2
strcpy_s(result, resultMaxSize, in1);
strcat_s(result, resultMaxSize, in2);
// All right
return TRUE;
}
而且它是由下面的C#控制檯應用程序代碼調用成功:
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace CSharpClient
{
class Program
{
[DllImport(
"NativeDll.dll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool NativeFunction(
string in1,
string in2,
StringBuilder result,
int resultMaxSize);
static void Main(string[] args)
{
var result = new StringBuilder(200);
if (! NativeFunction("Hello", " world!", result, result.Capacity))
{
Console.WriteLine("Error.");
return;
}
Console.WriteLine(result.ToString());
}
}
}
具有u試圖進口什麼? –
我試過類似:[DllImport(「MyDll」,EntryPoint =「NativeMethod」)] public static extern Boolean NativeMethod(string param1,string param2,string param3); 此外與出param3或StringBuilder或MarshalAs(UnmanagedType.LPStr)] – bit
您意識到,此輸出參數將無法正常工作? C#字符串是**不可變的**。 – antonijn