.Net 4 causes the DLLImport function to return a failure code; .Net 2, 3, or 3.5 does not

I am looking at an example project from sourceforge for communication with the TSAPI (not TAPI) telephone system - http://tsapi.sourceforge.net/ .

My development environment is 32-bit Windows XP, and the x86 target is set for the project.

This works fine, as provided for working with .Net 2, but I need to run it against .Net 4. When I change the structure and run the 1st function, it returns -1, indicating a failure.

Function Definition:

[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 # code (extracted from a sample project) to call this function:

    // 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);

An C ++ example application is also proposed, in which a function call:

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.

If I changed DLLImport to

[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);

I get a runtime error

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 */
+3
3

, char[], . , .net.

++ char*, . # string. p/invoke , # C, ToCharArray().

0

, 4.0, , , , 4.0, 64- .

, , csta32.dll DLL UInt32.

, ,

  • UInt32 uint, .

, , , , .

, , , .

0

The answer is to change the string char [] to a string. Then it works on .Net 4.0 - if you leave it as char [], it returns -2 (ACSERR_BADPARAMETER).

Therefore 2.0 should handle this, since this change is not required for DLLImport to work on this version of the framework.

0
source

All Articles