Tag: marshalling

如何在从C到C#的结构中获得非托管可变长度C数组?

如何返回MIB_IPFORWARDROW数组? struct MIB_IPFORWARDTABLE { public uint Size; [MarshalAs(/* what goes here? */)] public IPFORWARDROW[] Table; }; [DllImport(“iphlpapi”, CharSet = CharSet.Auto)] private static extern int GetIpForwardTable( IntPtr /* MIB_IPFORWARDTABLE* */ pIpForwardTable, ref uint /* ULONG* */ pdwSize, bool bOrder); public static MIB_IPFORWARDROW[] Temp() { var fwdTable = IntPtr.Zero; uint size = 0; var result = GetIpForwardTable(fwdTable, […]

将HBITMAP句柄从非托管代码传递到托管代码的安全性,以便创建System.Drawing.Bitmap

我是托管/非托管互操作的新手,所以我希望得到一些意见,了解以下过程如何安全地从非托管C ++到托管C#获取位图。 基本思路是: C#调用一个互操作函数FetchImage ,它位于非托管C ++中。 它通过一个out int param。 FetchImage有一个相应的long * param。 在C ++中, FetchImage创建一个安全的CBitmap ,即不是本地的,在其上绘制内容,使用HandleToLong()将位图的HBITMAP句柄转换为long ,将其存储在C#的参数中,然后返回。 回到C#, out int param转换为IntPtr并使用System.Drawing.Image.FromHbitmap复制数据并生成System.Drawing.Bitmap对象。 然后C#调用另一个互操作函数ReleaseImage 。 在C ++中, ReleaseImage释放与之前创建的CBitmap相关联的资源。 这是不耐烦的要点。 下面是更具体的代码示例。 函数的C ++互操作定义: namespace { std::unique_ptr bitty; } HRESULT __stdcall Helper::FetchImage( /*[out]*/ long * hBitmap ) { bitty.reset( new CBitmap ); // call CreateBitmap and then draw something, […]

Marshal.PtrToStructure抛出AccessViolationException

我有这个结构: [StructLayout(LayoutKind.Sequential)] public struct IS { public UInt32 ID; public UInt32 Quality; public UInt32 Flags; public UInt32 Flags2; public UInt32 ContainerSlots; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public Int32[] ItemStatType; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public UInt32[] ItemStatValue; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public Int32[] ItemStatUnk1; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public Int32[] ItemStatUnk2; public UInt32 ScalingStatDistribution; public UInt32 DamageType; […]

将C dll代码编组到C#中

我在dll中有以下C代码签名: extern __declspec(dllexport) unsigned char * funct_name (int *w, int *h, char **enc, int len, unsigned char *text, int *lp, int *mp, int *ep) C函数可以修改w,h,enc,lp,mp和ep(虽然后三者可以为null,但它不会做任何事情。 我在C#中使用以下内容 [DllImport(“iec16022ecc200.dll”, EntryPoint = “iec16022ecc200”, ExactSpelling = false, CharSet = CharSet.Ansi, SetLastError = true, CallingConvention=CallingConvention.Cdecl)] static extern IntPtr CallEncode( [In,Out,MarshalAs(UnmanagedType.LPArray)] Int32[] width, [In,Out,MarshalAs(UnmanagedType.LPArray)] Int32[] height, [In,Out,MarshalAs(UnmanagedType.LPStr)] ref StringBuilder encoding, int […]

如何将C函数签名转换为C#并在本机DLL中调用该函数?

int __stdcall getProps( /* [ in ] */ void * context, /* [ in ] */ const UINT32 index, /* [ in ] */ WCHAR * const pwszFilterPath, /* [ in, out ]*/ UINT32 * const pFilterPathSizeInCch, /* [ in ]*/ WCHAR * const pwszFilterName, /* [ in, out ] */ UINT32 * const pFilterNameSizeInCch […]

从c ++到C#的3D矢量结构

我正在尝试将我的引擎中的一些function从c ++移植到C#。 我使用非托管c ++编译我的引擎作为dll,并且只在C#包装器中使用extern“C”函数。 我有各种函数,可以获取并返回Vector3df 。 这被定义为 typedef Vector3d Vector3df; 而f32实际上是一个float 。 该类本身只有一些名为xy和z的成员以及许多方法。 我可以用C#重写整个课程,这不是问题,但无论如何,2可以匹配吗? 我们来举例说明以下函数: extern “C” void SetColor(Vector3df color) extern “C” Vector3df GetColor() 我希望在C#中有这样的东西: [DllImport(“Engine.dll”, EntryPoint = “SetColor”, CallingConvention = CallingConvention.Cdecl)] static extern void SetColor(Vector3df color); [DllImport(“Engine.dll”, EntryPoint = “GetColor”, CallingConvention = CallingConvention.Cdecl)] static extern Vector3df GetColor(); 无论如何,我可以使代码类似于这项工作吗? 请注意,我绝不是C#guru。我在编组方面失败了。 我主要是为了制作我的游戏的地图编辑器而不必学习Qt或wxWidgets。 谢谢!

C Struct的编组作为C#委托的返回值

我试图通过绑定到本机函数的委托的值返回一个小的(8字节)结构,但是在面向.NET Framework 2.0时遇到以下错误(代码似乎在定位4.0+时正常工作) : testclient.exe中发生了未处理的“System.AccessViolationException”类型exception 附加信息:尝试读取或写入受保护的内存。 这通常表明其他内存已损坏。 我怀疑我搞砸了托管类型注释,这样返回值没有被正确编组,但我看不出我做错了什么。 下面是一个小型本机测试DLL和托管客户端的代码,可以重现该问题。 C / C ++ Win32(x86)测试DLL //Natural alignment, blittable, sizeof(StatusBlock) == 8 struct StatusBlock{ std::uint32_t statusA; std::uint32_t statusB; }; /* * When compiled this function stores the 64bit return value in the * eax:edx register pair as expected. */ static StatusBlock __cdecl SomeFunction(std::uint32_t const someVal){ return StatusBlock{ […]

32位与64位版本类型的条件编译的首选方法

我需要某个任务来枚举系统中的所有句柄。 到目前为止,我发现的最好的方法是使用带有SystemHandleInformation标志的underdocumented NtQuerySystemInformation作为类参数。 到现在为止还挺好。 但是,在64位Windows上以32位模式运行它,所需的结构如下: // 32-bit version [StructLayout(LayoutKind.Sequential, Pack=1)] public struct SYSTEM_HANDLE_INFORMATION { public uint ProcessID; public byte ObjectTypeNumber; public byte Flags; public ushort Handle; public uint Object_Pointer; public UInt32 GrantedAccess; } 而对于64位Windows(x64,我没有测试Itanium,我希望没有什么不同……),结构如下: // 64-bit version [StructLayout(LayoutKind.Sequential, Pack=1)] public struct SYSTEM_HANDLE_INFORMATION { public int Reserved; // unknown, no documentation found public uint ProcessID; public […]

Marshal.GenerateGuidForType(Type)和Type.GUID之间有什么区别?

Type classType = typeof(SomeClass); bool equal = Marshal.GenerateGuidForType(classType) == classType.GUID; 我没有找到一个失败的情况。 那么为什么以及何时应该使用Marshal方法而不是简单地获取GUID属性?

如何正常卸载已运行线程的子AppDomain

我有一个加载子AppDomain的服务,然后启动一个在其中运行的线程。 它需要一个AppDomain,因为它动态生成并加载一些代码,我需要能够重新启动它而不会终止整个服务。 因此,在子AppDomain的事件循环中运行一个线程,它通过MarshalByRefObject传递给它的事件,MarshalByRefObject将东西粘在并发队列中。 我想停止并卸载子AppDomain并创建一个新的AppDomain。 我可以简单地在子AppDomain上调用Unload,但这将中止所有线程并抛出ThrearAbortException。 我怎样才能优雅地把它关掉? 如果我使用MarshalByRefObject在子AppDomain中设置一些静态标志,那么主进程如何能够等到它完成卸载? 我有一些示例代码,它显示了它的设置以及如何调用Unload来杀死它,我怎么能修改它以允许正常卸载并且永远不会有多个子AppDomains? using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security; using System.Security.Permissions; using System.Reflection; using System.Threading; namespace TestAppDomains { /// /// Calls to methods magically get transfered to the appdomain it was created in because it derives from MarshalByRefObject /// class MarshalProxy : MarshalByRefObject { public AppDomain […]