Я экспериментировал с этой новой функцией и решил использовать SymGetModuleInfo64 из dbghelp.dll в качестве примера. Я написал собственный маршаллер и могу его запустить (ниже приведен сгенерированный код), но он выдает исключение AccessViolationException, когда результат ConvertToManaged присваивается обратно ссылке. Нужен ли параметр ref специальной обработки? В настоящее время я просто создаю экземпляр IMAGEHELP_MODULE64 и устанавливаю его SizeOfStruct перед передачей его в SymGetModuleInfo64.
public unsafe partial class Test
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "7.0.10.26716")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
private static partial bool SymGetModuleInfo64(nint hProcess, long ModuleBase64, ref global::Test.Test.IMAGEHELP_MODULE64 imgHelpModule)
{
int __lastError;
global::Test.Test.IMAGEHELP_MODULE64_Marshaller.Unmanaged __imgHelpModule_native;
bool __retVal;
int __retVal_native;
// Marshal - Convert managed data to native data.
__imgHelpModule_native = global::Test.Test.IMAGEHELP_MODULE64_Marshaller.ConvertToUnmanaged(imgHelpModule);
{
System.Runtime.InteropServices.Marshal.SetLastSystemError(0);
__retVal_native = __PInvoke(hProcess, ModuleBase64, &__imgHelpModule_native);
__lastError = System.Runtime.InteropServices.Marshal.GetLastSystemError();
}
// Unmarshal - Convert native data to managed data.
__retVal = __retVal_native != 0;
-----> imgHelpModule = global::Test.Test.IMAGEHELP_MODULE64_Marshaller.ConvertToManaged(__imgHelpModule_native);
System.Runtime.InteropServices.Marshal.SetLastPInvokeError(__lastError);
return __retVal;
// Local P/Invoke
[System.Runtime.InteropServices.DllImportAttribute("dbghelp.dll", EntryPoint = "SymGetModuleInfo64", ExactSpelling = true)]
static extern unsafe int __PInvoke(nint hProcess, long ModuleBase64, global::Test.Test.IMAGEHELP_MODULE64_Marshaller.Unmanaged* imgHelpModule);
}
}
Я пытался выделить память для параметра, чтобы убедиться, что он принадлежит мне, но что бы я ни делал, я все равно получаю исключение AccessViolationException.
Вот как выглядит класс Test, который сгенерировал приведенный выше код (ПРИМЕЧАНИЕ: меня интересовал только LoadedPdbName, поэтому я не реализовал маршалинг для всей структуры, но это не должно иметь значения , PINvoke вызов успешен):
public unsafe partial class Test
{
[StructLayout(LayoutKind.Sequential)]
[NativeMarshalling(typeof(IMAGEHELP_MODULE64_Marshaller))]
private struct IMAGEHELP_MODULE64
{
public int SizeOfStruct;
public long BaseOfImage;
public int ImageSize;
public int TimeDateStamp;
public int CheckSum;
public int NumSyms;
public SymType SymType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string ModuleName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string ImageName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string LoadedImageName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string LoadedPdbName;
public int CVSig;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 780)]
public string CVData;
public int PdbSig;
public GUID PdbSig70;
public int PdbAge;
public bool PdbUnmatched;
public bool DbgUnmatched;
public bool LineNumbers;
public bool GlobalSymbols;
public bool TypeInfo;
public bool SourceIndexed;
public bool Publics;
public int MachineType;
public int Reserved;
}
[StructLayout(LayoutKind.Sequential)]
private struct GUID
{
public int Data1;
public ushort Data2;
public ushort Data3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] data4;
}
[Flags]
private enum SymType : uint
{
SymNone,
SymCoff,
SymCv,
SymPdb,
SymExport,
SymDeferred,
SymSym,
SymDia,
SymVirtual,
}
[CustomMarshaller(typeof(IMAGEHELP_MODULE64), MarshalMode.Default, typeof(IMAGEHELP_MODULE64_Marshaller))]
private static unsafe class IMAGEHELP_MODULE64_Marshaller
{
[StructLayout(LayoutKind.Explicit)]
public ref struct Unmanaged
{
[FieldOffset(0)] public int SizeOfStruct;
[FieldOffset(580)] public fixed byte LoadedPdbName[256];
}
public static Unmanaged ConvertToUnmanaged(IMAGEHELP_MODULE64 managed)
{
return new Unmanaged
{
SizeOfStruct = managed.SizeOfStruct
};
}
public static IMAGEHELP_MODULE64 ConvertToManaged(Unmanaged unmanaged)
{
return new IMAGEHELP_MODULE64
{
LoadedPdbName = AnsiStringMarshaller.ConvertToManaged(unmanaged.LoadedPdbName)
};
}
}
[LibraryImport("dbghelp.dll", StringMarshalling = StringMarshalling.Utf8, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool SymGetModuleInfo64(nint hProcess, long ModuleBase64,
ref IMAGEHELP_MODULE64 imgHelpModule);
}
И вот как он используется:
var moduleInfo = new IMAGEHELP_MODULE64();
moduleInfo.SizeOfStruct = Marshal.SizeOf(moduleInfo);
if (!SymGetModuleInfo64(_processPtr, _baseOfDll, ref moduleInfo))
throw new Win32Exception(Marshal.GetLastWin32Error());
Подробнее здесь: https://stackoverflow.com/questions/792 ... marshaling
Требуют ли ref-параметры специальной обработки при собственном маршалинге, сгенерированном исходным кодом? ⇐ C#
Место общения программистов C#
1734438172
Anonymous
Я экспериментировал с этой новой функцией и решил использовать SymGetModuleInfo64 из dbghelp.dll в качестве примера. Я написал собственный маршаллер и могу его запустить (ниже приведен сгенерированный код), но он выдает исключение AccessViolationException, когда результат ConvertToManaged присваивается обратно ссылке. Нужен ли параметр ref специальной обработки? В настоящее время я просто создаю экземпляр IMAGEHELP_MODULE64 и устанавливаю его SizeOfStruct перед передачей его в SymGetModuleInfo64.
public unsafe partial class Test
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "7.0.10.26716")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
private static partial bool SymGetModuleInfo64(nint hProcess, long ModuleBase64, ref global::Test.Test.IMAGEHELP_MODULE64 imgHelpModule)
{
int __lastError;
global::Test.Test.IMAGEHELP_MODULE64_Marshaller.Unmanaged __imgHelpModule_native;
bool __retVal;
int __retVal_native;
// Marshal - Convert managed data to native data.
__imgHelpModule_native = global::Test.Test.IMAGEHELP_MODULE64_Marshaller.ConvertToUnmanaged(imgHelpModule);
{
System.Runtime.InteropServices.Marshal.SetLastSystemError(0);
__retVal_native = __PInvoke(hProcess, ModuleBase64, &__imgHelpModule_native);
__lastError = System.Runtime.InteropServices.Marshal.GetLastSystemError();
}
// Unmarshal - Convert native data to managed data.
__retVal = __retVal_native != 0;
-----> imgHelpModule = global::Test.Test.IMAGEHELP_MODULE64_Marshaller.ConvertToManaged(__imgHelpModule_native);
System.Runtime.InteropServices.Marshal.SetLastPInvokeError(__lastError);
return __retVal;
// Local P/Invoke
[System.Runtime.InteropServices.DllImportAttribute("dbghelp.dll", EntryPoint = "SymGetModuleInfo64", ExactSpelling = true)]
static extern unsafe int __PInvoke(nint hProcess, long ModuleBase64, global::Test.Test.IMAGEHELP_MODULE64_Marshaller.Unmanaged* imgHelpModule);
}
}
Я пытался выделить память для параметра, чтобы убедиться, что он принадлежит мне, но что бы я ни делал, я все равно получаю исключение AccessViolationException.
Вот как выглядит класс Test, который сгенерировал приведенный выше код (ПРИМЕЧАНИЕ: меня интересовал только LoadedPdbName, поэтому я не реализовал маршалинг для всей структуры, но это не должно иметь значения , PINvoke вызов успешен):
public unsafe partial class Test
{
[StructLayout(LayoutKind.Sequential)]
[NativeMarshalling(typeof(IMAGEHELP_MODULE64_Marshaller))]
private struct IMAGEHELP_MODULE64
{
public int SizeOfStruct;
public long BaseOfImage;
public int ImageSize;
public int TimeDateStamp;
public int CheckSum;
public int NumSyms;
public SymType SymType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string ModuleName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string ImageName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string LoadedImageName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string LoadedPdbName;
public int CVSig;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 780)]
public string CVData;
public int PdbSig;
public GUID PdbSig70;
public int PdbAge;
public bool PdbUnmatched;
public bool DbgUnmatched;
public bool LineNumbers;
public bool GlobalSymbols;
public bool TypeInfo;
public bool SourceIndexed;
public bool Publics;
public int MachineType;
public int Reserved;
}
[StructLayout(LayoutKind.Sequential)]
private struct GUID
{
public int Data1;
public ushort Data2;
public ushort Data3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] data4;
}
[Flags]
private enum SymType : uint
{
SymNone,
SymCoff,
SymCv,
SymPdb,
SymExport,
SymDeferred,
SymSym,
SymDia,
SymVirtual,
}
[CustomMarshaller(typeof(IMAGEHELP_MODULE64), MarshalMode.Default, typeof(IMAGEHELP_MODULE64_Marshaller))]
private static unsafe class IMAGEHELP_MODULE64_Marshaller
{
[StructLayout(LayoutKind.Explicit)]
public ref struct Unmanaged
{
[FieldOffset(0)] public int SizeOfStruct;
[FieldOffset(580)] public fixed byte LoadedPdbName[256];
}
public static Unmanaged ConvertToUnmanaged(IMAGEHELP_MODULE64 managed)
{
return new Unmanaged
{
SizeOfStruct = managed.SizeOfStruct
};
}
public static IMAGEHELP_MODULE64 ConvertToManaged(Unmanaged unmanaged)
{
return new IMAGEHELP_MODULE64
{
LoadedPdbName = AnsiStringMarshaller.ConvertToManaged(unmanaged.LoadedPdbName)
};
}
}
[LibraryImport("dbghelp.dll", StringMarshalling = StringMarshalling.Utf8, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool SymGetModuleInfo64(nint hProcess, long ModuleBase64,
ref IMAGEHELP_MODULE64 imgHelpModule);
}
И вот как он используется:
var moduleInfo = new IMAGEHELP_MODULE64();
moduleInfo.SizeOfStruct = Marshal.SizeOf(moduleInfo);
if (!SymGetModuleInfo64(_processPtr, _baseOfDll, ref moduleInfo))
throw new Win32Exception(Marshal.GetLastWin32Error());
Подробнее здесь: [url]https://stackoverflow.com/questions/79286631/do-ref-parameters-need-special-handling-in-source-generated-native-marshaling[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия