3

TSAPI(TAPIではない)電話システムにリンクするためのsourceforgeのサンプルプロジェクトを探しています-http: //tsapi.sourceforge.net/

私の開発環境は32ビットWindowsXPで、プロジェクトはx86をターゲットに設定されています。

これは、.Net 2に対して実行するために提供されたとおりに正常に機能しますが、.Net 4に対して実行する必要があります。フレームワークを変更して実行すると、最初の関数は失敗を示す-1を返します。

関数の定義は次のとおりです。

[DllImport("csta32.dll")]
public static extern int acsOpenStream(ref UInt32 acsHandle, int invokeIDType, UInt32 invokeID, int streamType, char[] serverID, char[] loginID, char[] passwd, char[] applicationName, int acsLevelReq, char[] apiVer, ushort sendQSize, ushort sendExtraBufs, ushort recvQSize, ushort recvExtraBufs, ref PrivateData_t priv);

この関数を呼び出すためのc#コード(サンプルプロジェクトから抽出)は次のとおりです。

    // The public method to open the ACS stream
    public bool open(string strLoginId, string strPasswd, string strServerId)
    {
        // Convert the parameters to character arrays
        char[] serverId = strServerId.ToCharArray();
        char[] loginId = strLoginId.ToCharArray();
        char[] passwd = strPasswd.ToCharArray();

        // Define the initial set of variables used for opening the ACS Stream
        int invokeIdType = 1;
        UInt32 invokeId = 0;
        int streamType = 1;
        char[] appName = "Mojo".ToCharArray();
        int acsLevelReq = 1;
        char[] apiVer = "TS1-2".ToCharArray();
        ushort sendQSize = 0;
        ushort sendExtraBufs = 0;
        ushort recvQSize = 0;
        ushort recvExtraBufs = 0;

        // Define the mandatory (but unused) private data structure
        Csta.PrivateData_t privData = new Csta.PrivateData_t();
        privData.vendor = "MERLIN                          ".ToCharArray();
        privData.length = 4;
        privData.data = "N".ToCharArray();

        // Define the event buffer pointer that gets data back from the TServer
        ushort numEvents = 0;
        Csta.EventBuf_t eventBuf = new Csta.EventBuf_t();
        ushort eventBufSize = (ushort)Csta.CSTA_MAX_HEAP;

        // Open the ACS stream
        try
        {
            int openStream = Csta.acsOpenStream(ref acsHandle, invokeIdType, invokeId, streamType, serverId, loginId, passwd, appName, acsLevelReq, apiVer, sendQSize, sendExtraBufs, recvQSize, recvExtraBufs, ref privData);

関数呼び出しが次のC++サンプルアプリケーションも提供されています。

m_nRetCode = acsOpenStream(&m_lAcsHandle            // Handle for ACS Stream 
    , APP_GEN_ID            // APP_GEN_ID indicates Application   generated invokeID's
    , (InvokeID_t)m_ulInvokeID  // By default 1
    , ST_CSTA
    , (ServerID_t *)(serverID)  // AE Server Name
    , (LoginID_t *)(loginID)    // CTI LoginID
    , (Passwd_t *)(password)  // CTI LoginID password
    , (AppName_t *)"TSAPI_AgentView"
    , ACS_LEVEL1
    , (Version_t *) "TS1-2" // private Data version in use 8 in our case
    , 10
    , 5 
    , 50
    , 5
    , (PrivateData_t *)&m_stPrivateData); // private Data.

DLLImportをに変更した場合

[DllImport("csta32.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int acsOpenStream(ref UInt32 acsHandle, int invokeIDType, UInt32 invokeID, int streamType, char[] serverID, char[] loginID, char[] passwd, char[] applicationName, int acsLevelReq, char[] apiVer, ushort sendQSize, ushort sendExtraBufs, ushort recvQSize, ushort recvExtraBufs, ref PrivateData_t priv);

ランタイムエラーが発生します

PInvokeStackImbalanceが検出されましたメッセージ:PInvoke関数'Mojo!Csta :: acsOpenStream'の呼び出しにより、スタックのバランスが崩れました。これは、マネージドPInvokeシグニチャがアンマネージドターゲットシグニチャと一致しないことが原因である可能性があります。PInvokeシグニチャの呼び出し規約とパラメータがターゲットのアンマネージドシグニチャと一致することを確認してください。

Avayaはヘッダーファイルを提供していません-ドキュメントは関数定義が次のようになっていることを示しています:

RetCode_t acsOpenStream(
ACSHandle_t *acsHandle, /* RETURN */
InvokeIDType_t invokeIDType, /* INPUT */
InvokeID_t invokeID, /* INPUT */
StreamType_t streamType, /* INPUT */
ServerID_t *serverID, /* INPUT */
LoginID_t *loginID, /* INPUT */
Passwd_t *passwd, /* INPUT */
AppName_t *applicationName, /* INPUT */
Level_t acsLevelReq /* INPUT */
Version_t *apiVer, /* INPUT */
unsigned short sendQSize, /* INPUT */
unsigned short sendExtraBufs, /* INPUT */
unsigned short recvQSize, /* INPUT */
unsigned short recvExtraBufs /* INPUT */
PrivateData_t *privateData); /* INPUT */
4

3 に答える 3

0

4.0について話していることを考えると、提供された質問から推測するのは難しいと思います。4.0で実行するアプリケーションは64ビットOSでも実行されます。

その場合、失敗が絶対的に正当化される場合は、csta32.dllDLLをターゲットにして、同様のパラメーターを使用しますUInt32

これを修正するためのソリューションを進めるための最初のステップは、

  • インポートする適切なライブラリを選択する
  • substitudeUint32uintで指定すると、タイプの正しいディメンションが実行時に選択されます。

しかし、これらは当然のことながら、インポートするために宣言する必要がある正しいメソッドの正しい署名を尊重する必要があります。

これがあなたが求めているものではない場合、またはそれがあなたの問題ではない場合は、明確にしてください。

于 2012-04-20T21:58:07.897 に答える
0

答えは、char[]を文字列に修正することです。これは.Net4.0で機能します-char[]のままにすると、-2(ACSERR_BADPARAMETER)が返されます。

したがって、DLLImportがそのバージョンのフレームワークで機能するためにこの変更は必要ないため、2.0はこれを処理する必要があります。

于 2012-04-21T15:08:10.567 に答える
0

宣言した文字列パラメータchar[]は常に間違っていました。以前の.netバージョンでは、偶然にそれを回避したと思います。

C ++コードは、これらのパラメーターをchar*、つまりnullで終了する文字配列へのポインターとして宣言します。C#コードでこれらのパラメーターを宣言する正しい方法は次のとおりですstring。p / invokeマーシャラーがC#文字列をC文字列に変換し、すべての偽のToCharArray()コードを削除できます。

于 2012-04-21T15:38:39.200 に答える