对不起,下面是详细的介绍.我需要知道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++编写的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
首先让我说看看我在整个论坛和网络上的许多链接中找到了固定{},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) 我正在研究Scala和XML之间的编组/解组数据的各种方法,我有兴趣获得社区反馈(最好以第一手知识/经验为基础).
我们目前正在使用JAXB,这很好,但我希望有一个纯Scala解决方案.我正在考虑以下方法:
使用Scala的内置XML工具:Scala-> XML会很简单,但我的猜测是另一个方向会相当痛苦.另一方面,这种方法支持任意翻译逻辑.
数据绑定:scalaxb目前似乎有些不成熟,并且不处理我们当前的模式,我不知道Scala的任何其他数据绑定库.与JAXB一样,需要额外的转换层来支持相关的转换.
XML pickler组合器:GData Scala Client库提供XML pickler组合器,但是最近的项目活动一直很少,我不知道当前状态是什么.
问题:
编辑:
我在自己对这个问题的回答中添加了关于我对pickler组合器的早期印象的一些注释,但我仍然对那些真正了解各种方法的人的反馈非常感兴趣.我希望的是一个有点全面的比较,可以帮助开发人员选择适合他们需求的方法.
我想测试以下代码:
private bool TestException(Exception ex)
{
if ((Marshal.GetHRForException(ex) & 0xFFFF) == 0x4005)
{
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我想以Exception某种方式设置对象以返回正确的HResult,但我无法在Exception类中看到允许这样的字段.
我该怎么做?
我使用的是进程外COM服务器(使用DECLARE_CLASSFACTORY_SINGLETON实现的COM单例"引擎"),它在STA(CComSingleThreadModel,_ATL_APARTMENT_THREADED)中工作.
COM服务器客户端:
BHO定期调用Engine :: dispatchEvent,Engine调用ActiveScript的JavaScript函数.这种架构非常有效,直到我同时打开两个BHO.
如果我打开两个BHO,当我调用ActiveScript函数(使用IDispatch/Invoke)时会发生卡住.我没有创建任何额外的线程.
一些说明:
调用堆栈:
> 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) 我有以下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) 我正在C#(.NET 4.0)中构建一个COM对象,用于经典的asp站点.现在我想知道在组件和asp站点之间来回编组VB脚本数组(单维和多维)的正确方法是什么?代码示例将受到高度赞赏.
这给了我一个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)
有可能完成我想要完成的任务吗?
我需要将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)