0

我正在尝试使用 C# 中的 Powerbuilder ORCA Api,但我在编组方面遇到了一些问题。是 ORCA Api 的 C 头文件,我正在尝试实现 PBORCA_SccGetConnectProperties 函数,该函数需要 pborca_scc 结构。这是我的定义:

[DllImport(OrcaModule, CharSet = CharSet.Auto)]
internal static extern int PBORCA_SccGetConnectProperties(IntPtr ORCASession,
    [MarshalAs(UnmanagedType.LPWStr)] string Workspace,
    ref OrcaSccInfo SCCInfo);

public delegate int TextOutDelegate(
        [MarshalAs(UnmanagedType.LPWStr)] string data,
        int userData);

public delegate void BuildProjectDelegate(
        OrcaBuildError BuildError,
        IntPtr userData);

[StructLayout(LayoutKind.Sequential)]
public sealed class OrcaSccInfo
{
  internal IntPtr Wnd = IntPtr.Zero;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  internal string ProviderName = null;

  internal int Capabilities = 0;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  internal string UserID = null;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 301)]
  internal string Project = null;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 301)]
  internal string LocalProjPath = null;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 301)]
  internal string AuxPath = null;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 301)]
  internal string LogFile = null;

  internal TextOutDelegate SccMsgHandler = null;
  internal BuildProjectDelegate OrcaMsgHandler = null;
  internal int lCommentLen = 0;
  internal int lAppend = 0;
  internal IntPtr CommBlk = IntPtr.Zero;
  internal int DeleteTempFiles = 0;
}

像这样调用函数时:

ret = Interop.PBORCA_SccGetConnectProperties(session.Handle,
                @"D:\PB11-test\test.pbw",
                ref scc);

我收到一个 FatalExecutionEngineError 消息,它可能是由于编组错误。我一遍又一遍地重复这个问题,似乎找不到我在编组函数、结构或委托的方式上犯的错误。

4

1 回答 1

0

对于委托定义,第二个参数应该是 uint 而不是 int。

public delegate int TextOutDelegate([MarshalAs(UnmanagedType.LPWStr)] string data, uint userData);

第二个委托中的第一个参数可能是一个 ref 或一个指针。

public delegate void BuildProjectDelegate(ref OrcaBuildError BuildError, IntPtr userData);

在类定义中,您可以在委托成员以及任何接受委托的方法中尝试 [MarshalAs(UnmanagedType.FunctionPtr)]​​。

OrcaSccInfo 类在 C# 中的大小是否与您期望在 C++ 代码中的大小相同?当我将它放入 Linqpad 并获得大小时,Auto charset 为 2584,Ansi charset 为 1320,当我在 64 位上设置 Pack=1 和在 32 位上设置 1300 时,我得到 1316。

您是否尝试过用 StringBuilders 替换字符串,尤其是在 Dllimport 声明本身中?

是否有可能您的代表在被使用之前就被处理掉了?将委托传递给非托管代码不会创建垃圾收集器可以看到的引用,因此除非您在自己的代码中保留对委托的引用,否则它将比您预期的更早被处理掉。

于 2012-08-31T13:42:08.167 回答