Tag: marshalling

将C ++二维固定长度char数组封装为结构成员

我试图调用一个非托管C ++函数,它有一个结构作为输入参数。 结构在头文件中定义如下: struct MyStruct { int siOrder; char aaszNames[6][25]; int siId[6]; int siTones[6]; }; 我试图将托管结构声明如下: [StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)] public struct MyStruct { public int siOrder; [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst=150)] public string aaszNames; [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=6, ArraySubType=UnmanagedType.I4)] public int[] siId; [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=6, ArraySubType=UnmanagedType.I4)] public int[] siTones; } 但没有任何成功。 我猜测编组失败了,因为aaszNames实际上是一个由六个25长的空终止字符串组成的数组。 我尝试将aaszNames声明为 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=150)] public char[] aaszNames; 必要时用空值填充数组。 但是,再一次,没有。 有什么我想念的吗? 我错了什么? […]

我成功地从C#调用了advapi32的LsaEnumerateAccountRights()。 现在我如何解组它返回的LSA_UNICODE_STRING数组呢?

它是指向LSA_UNICODE_STRING结构数组的指针。 我找到了一些反向的代码,即从C#字符串创建一个LSA_UNICODE_STRING 。 您可以在下面的帮助程序代码部分中看到。 我所做的包括对LsaEnumerateAccountRights()的调用似乎工作得很好。 为数组指针和计数返回合理的值。 我不知道如何处理那些爆炸的字符串。 请帮忙? 好吗? 更新: nobugz的帮助函数在下面的答案中几乎是正确的,你只需UnicodeEncoding.CharSize来划分长度。 多亏了他,我现在可以在数组中看到FIRST字符串。 请参阅下面两个代码部分末尾的更新。 现在,我是如何做地狱世界的指针运算? 更新2.5:查看function代码的答案。 我丢失了旧的“错误”代码。

DllImport和char *

我有一个我想从DLL导入的方法,它有一个签名: BOOL GetDriveLetter(OUT char* DriveLetter) 我试过了 [DllImport(“mydll.dll”)] public static extern bool GetDriveLetter(byte[] DriveLetter); 和 [DllImport(“mydll.dll”)] public static extern bool GetDriveLetter(StringBuilder DriveLetter); 但是没有在DriveLetter变量中返回任何内容。

C ++中字符串的L前缀

我有一个静态库。 该库定义了以下function int WriteData(LPTSTR s) 调用该函数的示例是 LPTSTR s = (LPTSTR) L”Test Data”; int n = WriteData(s); WriteData在成功时返回0,在失败时返回-1。 我正在编写动态DLL来导出此函数。 int TestFun(LPTSTR lpData) { return WriteData(lpData); } C ++测试应用程序结果 LPTSTR s = (LPTSTR) L”Test Data”; TestFun(s); //OK return 0 LPTSTR s = (LPTSTR) “Test Data”; TestFun(s); //Fail return -1 我必须从ac#应用程序调用它。 我假设我的DLL-Import签名是: [DllImport(“Test.dll”)] private static extern int TestFun(String […]

blittable类型的非blittable错误

我有这个结构和这段代码: [StructLayout(LayoutKind.Sequential, Pack = 8)] private class xvid_image_t { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public int[] stride; // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] // public IntPtr[] plane; } public int decore() { xvid_image_t myStruct = new xvid_image_t(); myStruct.stride = new int[4]; // can be commented out – same result GCHandle.Alloc(myStruct, GCHandleType.Pinned); // … } 当我尝试运行它时,我得到一个ArgumentException : 对象包含非原始或非blittable数据 […]

使用LayoutKind.Explicit的布尔编组,这是否已按设计破坏或失败?

首先,布尔类型被称为具有四字节值的默认编组类型。 以下代码有效: struct A { public bool bValue1; public int iValue2; } struct B { public int iValue1; public bool bValue2; } public static void Main() { int[] rawvalues = new int[] { 2, 4 }; A a = (A)Marshal.PtrToStructure(GCHandle.Alloc(rawvalues, GCHandleType.Pinned).AddrOfPinnedObject(), typeof(A)); Assert.IsTrue(a.bValue1 == true); Assert.IsTrue(a.iValue2 == 4); B b = (B)Marshal.PtrToStructure(GCHandle.Alloc(rawvalues, GCHandleType.Pinned).AddrOfPinnedObject(), typeof(B)); Assert.IsTrue(b.iValue1 […]

Marshal.PtrToStructure抛出System.ArgumentException错误

我试图从键盘钩子的lParam获取KBDLLHOOKSTRUCT。 private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { KBDLLHOOKSTRUCT kbd = new KBDLLHOOKSTRUCT(); Marshal.PtrToStructure(lParam, kbd); // Throws System.ArguementException … 不幸的是,PtrToStructure正在投掷两个 A first chance exception of type ‘System.ArgumentException’ occurred in myprogram.exe 每次按下一个键都会出错。 它也会阻止该方法的发展。 MSNDA说: http : //msdn.microsoft.com/en-us/library/4ca6d5z7.aspx ArgumentException when: The structureType parameter layout is not sequential or explicit. -or- The structureType parameter is […]

将字节数组封送到C#结构

我正在研究用于读取FAT32引导扇区和BPB的C#项目,问题是我正在使用编组机制将字节数组转换为自定义FAT32数据结构。 我收到一条消息错误说:无法从程序集’FAT32Management,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null’加载类型’FAT32Management.Fat32BootSector’,因为它包含偏移3处的对象字段,该字段未正确对齐或重叠由非对象字段。 我无法解决问题 这是代码 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; namespace FAT32Management { [StructLayout(LayoutKind.Explicit)]//, CharSet = CharSet.Ansi, Size = 96, Pack = 1)] public struct Fat32BootSector { #region Common Region With all FAT systems /// /// First 3 Bytes of the Jump insctructions. /// Offset […]

Marshal.FreeHGlobal应该放在finally块中以确保资源处置?

我有以下代码块: IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length); SomeCommandThatCanThrowAnException(); Marshal.FreeHGlobal(unmanagedPointer); 是否应该在try中包装块,并将FreeHGlobal命令放在finally块中。 (如果middle命令抛出exception)。 在这种情况下最终会阻止内存泄漏似乎是有道理的,但是从我在网上找到的例子中,最终没有使用。 也许资源会被自动处理掉(即使它们是不受管理的)。

如何使用C#获取char **?

我需要以下列forms将参数传递给不安全的DllImported函数: [DllImport(“third_party.dll”)] private static extern unsafe int start(int argc, char** argv); 我假设它是一个字符串数组。 但是,当我尝试执行以下操作时,我得到’无法从字符串[]转换为char **’错误。 我如何让这个工作? 谢谢。 string[] argv = new string[] { }; start(0, argv); 编辑1:问题被标记为重复,但看着可能重复的问题,我仍然没有看到如何使这个工作。 编辑2:进一步确定问题和所需参数。 它看起来像您的标准argc / argv参数(参数计数,然后是参数值)。 与启动ac程序的方式相同: int main(int argc, char** argv); 对于这个特殊问题,我根本不想传递任何参数(因此count为0)。 编辑3:我从第三方库供应商那里获得了更多信息。 这里是: 第一个参数是参数计数 第二个参数是一个以空字符结尾的字符串数组 字符串是ANSI编码的 编辑4 :使用工作解决方案进行最终编辑(至少在我的情况下)。 我会把它作为答案,但不能,因为这个问题被标记为重复。 这是一个帮助我最多的问题的链接 。 最后,dll函数需要一个指向ANSI字符串缓冲区的指针数组。 所以我的最终方法(基于相关问题)如下。 在内存中创建一个数组来保存指针,然后将每个字符串分配到内存中的其他位置,并在第一个指针数组中写入指向这些字符串的指针。 此代码适用于生产: [DllImport(“third_party.dll”, CallingConvention = CallingConvention.Cdecl, […]