【发布时间】:2011-01-12 08:57:02
【问题描述】:
我正在尝试调用我拥有 C++ 标头的 dll 中的方法。我正在从 C# 调用 dll。输入是字符串,输出是二进制数据。以下 3 种方法中的任何一种都可能有效,我只是不知道如何使它们中的任何一种一直有效。 C#声明是我做的,所以可能不正确
1:我可以获取hGlobal,但我不知道如何从句柄获取数据。
//CMBT_LL_WINAPI INT DLLPROC LlConvertStringToHGLOBALW(LPCWSTR pszText, _PHGLOBAL phMemory);
[DllImport("cmll15.dll", EntryPoint = "LlConvertStringToHGLOBALW", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern int _LlConvertStringToHGlobal32(string text, ref IntPtr handle);
2:
[DllImport("cmll15.dll", EntryPoint = "LlConvertStringToBLOBW", CharSet = CharSet.Unicode, ExactSpelling = true)]
//CMBT_LL_WINAPI INT DLLPROC LlConvertStringToBLOBW(LPCWSTR pszText, _PUINT8 pBytes, UINT nBytes);
private static extern int _LlConvertStringToBLOBW(string text, ref IntPtr pBytes, UInt32 nBytes);
3:
[DllImport("cmll15.dll", EntryPoint = "LlConvertStringToStreamW", CharSet = CharSet.Unicode, ExactSpelling = true)]
//CMBT_LL_WINAPI INT DLLPROC LlConvertStringToStreamW(LPCWSTR pszText, _PISTREAM pStream);
private static extern int _LlConvertStringToStreamW(string text, ref IntPtr pStream);
已更新,这是我想我最终会得到的代码。
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
private static extern UIntPtr GlobalSize(IntPtr hMem);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GlobalLock(IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GlobalUnlock(IntPtr handle);
[DllImport("cmll15.dll", EntryPoint = "LlConvertStringToHGLOBALW", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern int _LlConvertStringToHGlobal32(string text, ref IntPtr handle);
private static void Main(string[] args)
{
IntPtr dataHandle = IntPtr.Zero;
_LlConvertStringToHGlobal32(Contents, ref dataHandle);
try
{
var size = (uint) GlobalSize(dataHandle);
var array = new byte[size];
IntPtr dataPtr = GlobalLock(dataHandle);
try
{
Marshal.Copy(dataPtr, array, 0, array.Length);
}
finally
{
GlobalUnlock(dataPtr);
}
using (var fs = new FileStream("c:\\file.dat", FileMode.Create))
{
fs.Write(array, 0, array.Length);
}
}
finally
{
Marshal.FreeHGlobal(dataHandle);
}
}
【问题讨论】:
-
你试过编译和运行它们吗?指定问题以便我们理解。
-
如果您已经指定了
CharSet.Unicode,为什么还要指定ExactSpelling和EntryPoint?这些都是多余的。 -
我不认为我的问题是关于从 C++ 到 C# 的方法的翻译,但我不知道,我只是展示了它们,所以你可能会发现任何错误。我认为 C# 签名是正确的,但我现在不知道调用方法或使用方法的给定输出
标签: c# c++ marshalling