0

C#のPowerbuilder ORCA Apiを使用しようとしていますが、マーシャリングに問題があります。これがORCAApiのCヘッダーファイルです。pborca_scc構造体を必要とするPBORCA_SccGetConnectProperties関数を実装しようとしています。これが私の定義です:

[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

デリゲート定義の場合、その2番目のパラメーターはintではなくuintである必要があります。

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

2番目のデリゲートの最初のパラメーターは、refまたはポインターである可能性があります。

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

また、クラス定義では、デリゲートメンバー、およびデリゲートを受け取る任意のメソッドで[MarshalAs(UnmanagedType.FunctionPtr)]を試すことができます。

OrcaSccInfoクラスのサイズはC#でC ++コードで期待されるのと同じサイズになりますか?それをLinqpadに入れてサイズを取得すると、自動文字セットで2584、Ansi文字セットで1320、64ビットでPack = 1、32ビットで1300に設定すると1316になります。

特にDllimport宣言自体で、文字列をStringBuildersに置き換えてみましたか?

また、代理人が使用される前に処分される可能性はありますか?アンマネージコードにデリゲートを渡すと、ガベージコレクターが認識できる参照が作成されないため、独自のコードでデリゲートへの参照を保持しない限り、予想よりも早く破棄されます。

于 2012-08-31T13:42:08.167 に答える