在获取C#P / Invoke调用C ++ dll的正确参数时出现问题

时间:2010-03-22 15:53:50

标签: c# oracle pinvoke

尝试从Oracle的Outside In API中交叉功能。 具有以下功能:

SCCERR EXOpenExport {VTHDOC hDoc, VTDWORD dwOutputId, VTDWORD dwSpecType, 
VTLPVOID pSpec, VTDWORD dwFlags, VTSYSPARAM dwReserved, VTLPVOID pCallbackFunc, 
VTSYSPARAM dwCallbackData, VTLPHEXPORT phExport);

从头文件中我将参数减少为:
    typedef VTSYSPARAM VTHDOC,VTLPHDOC *
    typedef DWORD_PTR VTSYSPARAM
    typedef unsigned long DWORD_PTR

typedef unsigned long VTDWORD   

typedef VTVOID* VTLPVOID  
#define VTVOID void  

typedef VTHDOC VTHEXPORT, *VTLPEXPORT  
These are for 32 bit windows 

浏览头文件,示例程序和我找到的文档:
1. pSpec可以是指向缓冲区或NULL的指针,因此我将其设置为IntPtr.Zero(文档)。
2. dwFlags和dwReserved根据文档“必须由开发人员设置为0” 3.如果我不想处理回调,那么pCallbackFunc可以设置为NULL 4.最后两个是基于我使用[StructLayout(LayoutKind.Sequential)]编写C#包装器的结构。然后通过首先使用Marshal.AllocHGlobal(Marshal.SizeOf(instance))创建一个IntPtr,然后获取作为dwCallbackData的uint和phExport的IntPtr传递的地址值来实例化实例并生成参数。

最终参数列表如下: 1. phDoc作为IntPtr,由DAOpenDocument函数加载一个地址调用     之前。
2. dwOutputId为uint设置为1535,代表FI_JPEGFIF
3. dwSpecType为int设置为2,表示IOTYPE_ANSIPATH
4. pSpec作为IntPtr.Zero,输出将被写入 5. dwFlags as uint按指示设置为0 6. dwReserved当uint按指示设置为0时 7. pCallbackFunc as IntPtr设置为NULL,因为我将处理结果
8. dwCallBackDate as uint结构缓冲区的地址
9. phExport作为IntPtr到另一个结构缓冲区

仍然会从API中获得未定义的错误。这意味着该调用返回一个未在任何头文件中定义的961。在过去,当我选择的参数类型不正确时,我已经得到了这个 我开始使用Interop Assistant,它有助于学习有多少参数类型被翻译。然而,它受限于我能够从头文件中收集正确的本机类型。例如,前面函数中使用的hDoc参数被定义为非文件系统句柄,因此尝试使用Marshal创建句柄,然后使用IntPtr,最后它变成了一个int(实际上它是& phDoc这里使用) 除了反复试验之外,还有更科学的方法吗? 吉姆

1 个答案:

答案 0 :(得分:0)

您可以在http://pinvoke.net搜索现有解决方案,也可以尝试PInvoke Signature Toolkit。这些可能会提供一些帮助。