我在調用一個非託管C++ dll,期望char *作爲其參數之一,並且我想將一個字節[]插入它。該項目是用VB.NET編寫的。vb.net byte [] to C++ char *
什麼類型的編組將爲此工作?
我在調用一個非託管C++ dll,期望char *作爲其參數之一,並且我想將一個字節[]插入它。該項目是用VB.NET編寫的。vb.net byte [] to C++ char *
什麼類型的編組將爲此工作?
我不是.net專家,但我最近需要做類似的事情。
它不只是一個系列化的事,你也不得不從,而它在C++的土地被用來清理你的字節數組停止垃圾收集器...
的C#以下代碼段應該有所幫助。
// pin the byte[] (byteArray) GCHandle handle = GCHandle.Alloc(byteArray, GCHandleType.Pinned); IntPtr address = handle.AddrOfPinnedObject(); // Do your C++ stuff, using the address pointer. // Cleanup handle.Free();
如果您需要固定託管結構以將其作爲參數傳遞,則可以使用以下代碼。
// (c) 2007 Marc Clifton
/// <summary>
/// A helper class for pinning a managed structure so that it is suitable for
/// unmanaged calls. A pinned object will not be collected and will not be moved
/// by the GC until explicitly freed.
/// </summary>
internal class PinnedObject<T> : IDisposable where T : struct
{
protected T managedObject;
protected GCHandle handle;
protected IntPtr ptr;
protected bool disposed;
public T ManangedObject
{
get
{
return (T)handle.Target;
}
set
{
Marshal.StructureToPtr(value, ptr, false);
}
}
public IntPtr Pointer
{
get { return ptr; }
}
public int Size
{
get { return Marshal.SizeOf(managedObject); }
}
public PinnedObject()
{
managedObject = new T();
handle = GCHandle.Alloc(managedObject, GCHandleType.Pinned);
ptr = handle.AddrOfPinnedObject();
}
~PinnedObject()
{
Dispose();
}
public void Dispose()
{
if (!disposed)
{
if (handle.IsAllocated)
handle.Free();
ptr = IntPtr.Zero;
disposed = true;
}
}
}
}
然後,您可以使用PinnedObject.Pointer調用非託管代碼。在你的extern聲明中,使用IntPtr作爲該參數的類型。
PinnedObject<BatteryQueryInformation> pinBatteryQueryInfo = new PinnedObject<BatteryQueryInformation>();
pinBatteryQueryInfo.ManangedObject = _structBatteryQueryInfo;
Unmanaged.Method(pinBatteryQueryInfo.Pointer);
在您的PInvoke定義中,只需將char *參數聲明爲byte [],標準編組將處理工作。
但這可能是也可能不是最好的主意。 C++函數需要一個字符串還是期待一個數據緩衝區(C/C++代碼通常使用char *作爲緩衝區,依賴於char是一個字節的事實)?
如果它是一個緩衝區,那麼一個字節[]當然是正確的,但如果它期望一個字符串,那麼它可能會更清晰,如果你聲明參數爲一個字符串(顯式),並使用Encoding.ASCII.GetString )將字節[]轉換爲字符串。
此外,如果它的C++函數需要字符串並決定聲明參數作爲字節[],確保字節數組具有零結束,因爲這是C/C++如何確定字符串的末尾。