Я вызываю неуправляемую DLL C++, которая ожидает, что char * будет одним из его параметров, и я хочу нажать на него байт []. Проект написан на VB.NET.vb.net byte [] to C++ char *
Какой тип сортировки будет работать для этого?
Я вызываю неуправляемую DLL C++, которая ожидает, что 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 просто объявить символ * параметр как байт [] и стандартной ИАС будет обрабатывать работу.
Но это может быть или не быть лучшей идеей. Является ли функция C++ ожидающей строки или ожидает буфера данных (код C/C++ часто использует char * для буфера, полагаясь на то, что char является одним байтом)?
Если это буфер, то байт [] определенно правильный, но если он ожидает строку, то может быть яснее, если вы объявите параметр как строку (явную) и используйте Encoding.ASCII.GetString () для преобразования байта [] в строку.
Также, если функция C++ ожидает строку, и вы решите объявить этот параметр как байт [], убедитесь, что массив байтов заканчивается нулем, так как это означает, что C/C++ определяет конец строки.