标签: marshalling

C#P/Invoke:包含函数指针的编组结构

对不起,下面是详细的介绍.我需要知道P/Invoke内部人员的洞察力比我更好.

这是我如何编组包含从C到C#的函数指针的结构.我想知道这是否是最干净和/或最有效的方式.

我正在使用C编码的本机DLL连接,它提供以下入口点:

void* getInterface(int id);
Run Code Online (Sandbox Code Playgroud)

您必须传递getInterface(int)以下枚举值之一:

enum INTERFACES
{
  FOO,
  BAR
};
Run Code Online (Sandbox Code Playgroud)

它返回一个指向包含函数指针的结构的指针,如:

typedef struct IFOO
{
  void (*method1)(void* self, int a, float b);
  void (*method2)(void* self, int a, float b, int c);
} IFoo;
Run Code Online (Sandbox Code Playgroud)

以下是您在C中使用它的方式:

IFoo* interface = (IFoo*)getInterface(FOO);
interface->method1(obj, 0, 1.0f); // where obj is an instance of an object
                                  // implementing the IFoo interface.
Run Code Online (Sandbox Code Playgroud)

在C#中,我有一个使用P/Invoke Library映射getInterface(int)入口点的类.

class Library
{
  [DllImport("MyDLL"), EntryPoint="getInterface", CallingConvention=CallingConvention.Cdecl)]
  public static extern IntPtr GetInterface(int id);
};
Run Code Online (Sandbox Code Playgroud)

然后我定义了:

struct …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke structure function-pointers marshalling

15
推荐指数
2
解决办法
9790
查看次数

使用C#中的Marshal.StructureToPtr将结构传递给C++ API

我在我的代码中使用C++编写的API(用C#编写).API需要一个参数作为指向结构的指针.结构由"Int"和Char Arrays组成:例如

 unsafe public struct ToBePassed 
    { 
        Int32 Num1;
        Int32 Num2; 
        Char[] Data; // or fixed Char Data[255];
    }
Run Code Online (Sandbox Code Playgroud)

我不能直接将结构指针传递给API,因为在这种情况下,我收到错误,因为"指针不能引用Marshaled结构".代码编译成功但是当我执行(调试)代码时会出现此错误.

现在我有两个选择:第一: - 通过参考传递结构:我想问一下当我通过ref传递结构时,需要结构指针的API是否可以接收地址.请注意,API将在"Char [] Data"中返回Data.

第二: - 使用Marshal.StructureToPtr:这会将结构指针转换为IntPtr.怀疑是相同的,API会正确接收吗?

谢谢你的时间!

此致,Swanand

c# struct marshalling

15
推荐指数
1
解决办法
2万
查看次数

了解使用fixed {},Marshal.AllocHGlobal()和GCHandle.Alloc()之间的区别

首先让我说看看我在整个论坛和网络上的许多链接中找到了固定{},Marshal.AllocHGlobal()和GCHandle.Alloc()的使用说明.但是,我还没有找到关于何时使用Marshal类与GCHandle类(使用和不使用fixed {})的简明解释.

我正在使用第三方.NET库,它在"Buffer"类中有一个名为Readline()的方法.该手册显示了以下函数原型:

bool ReadLine(int x1,int y1,int x2,int y2,System.IntPtr bufData,out int numRead);

描述bufData,说明:...内存区域的字节数必须大于或等于行长度乘以BytesPerPixel属性返回的值.

现在,后来在他们的用户手册,给访问该缓冲区(我已经调整了我的具体的例子一点点)的例子:

// Create an array large enough to hold one line from buffer
int size = 640; 
byte[] dataLine = new byte[size * 2];   // 2 bytes per pixel

// Pin the array to avoid Garbage collector moving it  
GCHandle dataLineHandle = GCHandle.Alloc(dataLine, GCHandleType.Pinned); 
IntPtr dataLineAddress = dataLineHandle.AddrOfPinnedObject(); 
Run Code Online (Sandbox Code Playgroud)

我可以按照上面的"示例"代码:

// Read one line of buffer data 
success = buffer.ReadLine(0, 0, 639, 0, …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke marshalling

15
推荐指数
1
解决办法
7230
查看次数

在Scala中编组/解组XML

我正在研究Scala和XML之间的编组/解组数据的各种方法,我有兴趣获得社区反馈(最好以第一手知识/经验为基础).

我们目前正在使用JAXB,这很好,但我希望有一个纯Scala解决方案.我正在考虑以下方法:

  1. 使用Scala的内置XML工具:Scala-> XML会很简单,但我的猜测是另一个方向会相当痛苦.另一方面,这种方法支持任意翻译逻辑.

  2. 数据绑定:scalaxb目前似乎有些不成熟,并且不处理我们当前的模式,我不知道Scala的任何其他数据绑定库.与JAXB一样,需要额外的转换层来支持相关的转换.

  3. XML pickler组合器:GData Scala Client库提供XML pickler组合器,但是最近的项目活动一直很少,我不知道当前状态是什么.

问题:

  1. 您对我列出的方法/库有什么经验?
  2. 每个的相对优势和劣势是什么?
  3. 我还应该考虑其他方法或Scala库吗?

编辑:

我在自己对这个问题的回答中添加了关于我对pickler组合器的早期印象的一些注释,但我仍然对那些真正了解各种方法的人的反馈非常感兴趣.我希望的是一个有点全面的比较,可以帮助开发人员选择适合他们需求的方法.

xml scala marshalling unmarshalling

15
推荐指数
1
解决办法
5074
查看次数

如何使用某个HResult抛出异常?

我想测试以下代码:

private bool TestException(Exception ex)
{
    if ((Marshal.GetHRForException(ex) & 0xFFFF) == 0x4005)
    {
        return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

我想以Exception某种方式设置对象以返回正确的HResult,但我无法在Exception类中看到允许这样的字段.

我该怎么做?

c# testing exception marshalling hresult

15
推荐指数
1
解决办法
8400
查看次数

进程外COM服务器卡住了

我使用的是进程外COM服务器(使用DECLARE_CLASSFACTORY_SINGLETON实现的COM单例"引擎"),它在STA(CComSingleThreadModel,_ATL_APARTMENT_THREADED)中工作.

COM服务器客户端:

  1. ActiveScript(JScript),(我使用AddNamedItem传递Engine引用).
  2. 两个独立的IE BHO.

BHO定期调用Engine :: dispatchEvent,Engine调用ActiveScript的JavaScript函数.这种架构非常有效,直到我同时打开两个BHO.

如果我打开两个BHO,当我调用ActiveScript函数(使用IDispatch/Invoke)时会发生卡住.我没有创建任何额外的线程.

一些说明:

  • 如果我没有将从BHO检索到的对象传递给ActiveScript(或者用在Engine中创建的相同对象替换它),一切正常.
  • 仅当JScript垃圾收集器尝试释放从BHO检索到的对象(callstack中的IUnknown_Release_Proxy)时才会发生Stuck.

调用堆栈:

>    ntdll.dll!_ZwWaitForMultipleObjects@20()  + 0x15 bytes    
 ntdll.dll!_ZwWaitForMultipleObjects@20()  + 0x15 bytes    
 KernelBase.dll!_WaitForMultipleObjectsEx@20()  + 0x100 bytes    
 kernel32.dll!_WaitForMultipleObjectsExImplementation@20()  + 0x8e bytes    
 user32.dll!_RealMsgWaitForMultipleObjectsEx@20()  + 0xe2 bytes    
 ole32.dll!CCliModalLoop::BlockFn(void * * ahEvent, unsigned long cEvents, unsigned long * lpdwSignaled)  Line 1222    C++
 ole32.dll!ModalLoop(CMessageCall * pcall)  Line 211    C++
 ole32.dll!ThreadSendReceive(CMessageCall * pCall)  Line 4979    C++
 ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall(CMessageCall * * ppCall)  Line 4454 + 0x6 bytes    C++
 ole32.dll!CRpcChannelBuffer::SendReceive2(tagRPCOLEMESSAGE * pMessage, unsigned long * pstatus)  Line 4076    C++ …
Run Code Online (Sandbox Code Playgroud)

windows com atl marshalling active-script

15
推荐指数
1
解决办法
1854
查看次数

如何编组一个可变大小的结构数组?C#和C++互操作帮助

我有以下C++结构

struct InnerStruct
{
   int A;
   int B;
};

struct OuterStruct
{
   int numberStructs;
   InnerStruct* innerStructs;
};
Run Code Online (Sandbox Code Playgroud)

还有一个C++函数

OuterStruct getStructs();
Run Code Online (Sandbox Code Playgroud)

我如何将其编组为C#?C#定义的位置

struct OuterStruct {
   InnerStruct[] innerStructs;
};
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke interop marshalling

14
推荐指数
1
解决办法
5791
查看次数

如何正确编组VB脚本数组与用C#编写的COM组件编组

我正在C#(.NET 4.0)中构建一个COM对象,用于经典的asp站点.现在我想知道在组件和asp站点之间来回编组VB脚本数组(单维和多维)的正确方法是什么?代码示例将受到高度赞赏.

.net arrays com-interop marshalling asp-classic

14
推荐指数
1
解决办法
5114
查看次数

如何将JAXB对象封送到org.w3c.dom.Document?

这给了我一个Document对象,其顶级节点没有子节点:

public static Document getDocument(Object jaxb)
{
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    //dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().newDocument(); 

    JAXBContext context = JAXBContext.newInstance(jaxb.getClass());
    context.createMarshaller().marshal(jaxb, doc);

    return doc;
}
Run Code Online (Sandbox Code Playgroud)

这是解决方法,它看起来效率更低,因为它转换为String然后转换为Document.

public static Document getDocument(Object jaxb)
{                           
    StringWriter writer = new StringWriter();       
    JAXBContext context = JAXBContext.newInstance(jaxb.getClass());
    context.createMarshaller().marshal(jaxb, writer);

    return DocumentBuilderFactory.newInstance().newDocumentBuilder().
parse(new InputSource(new StringReader(writer.toString()));
}
Run Code Online (Sandbox Code Playgroud)

有可能完成我想要完成的任务吗?

java xml dom jaxb marshalling

14
推荐指数
2
解决办法
4万
查看次数

C#interop:固定和MarshalAs之间的不良交互

我需要将C#4.0中的一些嵌套结构封装成二进制blob以传递给C++框架.

到目前为止,我使用unsafe/ fixed处理原始类型的固定长度数组已经取得了很大的成功.现在我需要处理一个包含其他结构的嵌套固定长度数组的结构.

我正在使用复杂的变通方法来展平结构,但后来我遇到了一个MarshalAs属性的例子,看起来它可以省去很多问题.

不幸的是,虽然它给了我正确的数据,它似乎也阻止了fixed阵列被正确编组,正如该程序的输出所示.您可以通过在最后一行放置断点并检查每个指针的内存来确认失败.

using System;
using System.Threading;
using System.Runtime.InteropServices;

namespace MarshalNested
{
  public unsafe struct a_struct_test1
  {
    public fixed sbyte a_string[3];
    public fixed sbyte some_data[12];
  }

  public struct a_struct_test2
  {
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public sbyte[] a_string;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public a_nested[] some_data;
  }

  public unsafe struct a_struct_test3
  {
    public fixed sbyte a_string[3];
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public a_nested[] some_data;
  }


  public unsafe struct a_nested
  {
    public fixed …
Run Code Online (Sandbox Code Playgroud)

c# interop unsafe marshalling

14
推荐指数
1
解决办法
596
查看次数