c#调用c++dll,结构体数组怎么传参?

时间:2022-08-30 19:56:18
有个项目需要调用第三方c++编写的dll,总是不行,要么提示参数无效,要么提示内部错误,晕的已经不行了,跪求指正。
c++函数头文件里面的声明:

BOOL WINAPI GAPICreateTypeW(
    LPCWSTR                     lpszProjectFile,
    LPDM_TYPE_DESCRIPTORW       lpdmType,
    DWORD                       dwFlags,
    DWORD                       dwCreatorID,
    LPMCP_NEWVARIABLE_DATA_EXW  lpMemberdata,
    LPCMN_ERRORW                lpdmError);


我的一些代码:


 [DllImport("dmclient.dll", EntryPoint = "GAPICreateTypeW", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
        public static extern bool GAPICreateType([In]  StringBuilder lpszProjectFile,
                                                       [In, Out] [MarshalAs(UnmanagedType.LPStruct)]
                                                        DM_TYPE_DESCRIPTOR lpdmType,
                                                       [In] UInt32 dwFlags,
                                                       [In] UInt32 dwCreatorID,
                                                        [In] [MarshalAs(UnmanagedType.LPArray)]
                                                         MCP_NEWVARIABLE_DATA_EX[] lpMemberdata,
                                                       [In, Out] [MarshalAs(UnmanagedType.LPStruct)]
                                                        CMN_ERROR lpdmError
                                                            );                    


我的调用方法:

 public bool CreateStructType(string TypeName, string GroupName,S7Struct s7struct, ref CMN_ERROR err)
        {
            if (TypeName == "")
            {
                err.szErrorText = "变量名为空!";
                return false;
            }
            DM_TYPE_DESCRIPTOR dmType = new DM_TYPE_DESCRIPTOR();
            dmType.dmTypeRef.dwType = MDM_TAG_TYPE.DM_VARTYPE_STRUCT;
            dmType.dmTypeRef.dwSize = 0;
            dmType.dmTypeRef.szTypeName = TypeName;
            

            //这部分只是对dmMembers数组的赋值
            List<MCP_NEWVARIABLE_DATA_EX> dmMemberList = new List<MCP_NEWVARIABLE_DATA_EX>();
            winccstruct2(s7struct.External, ref dmMemberList, true, GroupName, "");
            winccstruct2(s7struct.Internal, ref dmMemberList, true, GroupName, "");
            MCP_NEWVARIABLE_DATA_EX[] dmMembers = new MCP_NEWVARIABLE_DATA_EX[dmMemberList.Count];
            dmType.dmType.dmArray.dwNumElements = (uint)dmMemberList.Count;

            for (int i = 0; i < dmMemberList.Count; i++)
            {
                dmMembers[i] = dmMemberList[i];

            }

          


           
            bool ret;
            StringBuilder sbProjectFile = new StringBuilder(255);
            sbProjectFile.Append(ProjectFile.ToCharArray());
            ret = DMClient.GAPICreateType(sbProjectFile, dmType, 1, 0, dmMembers, err);

            return ret;
           
        }








下面是他的一个调用事例:

//{{ODK_EXAMPLE}Create structured variable (MCP)}
//{{FUNCTION}GAPICreateType (MCP)}
//{{FUNCTION}(END)}
// =====================================================================
// Function:    MyGAPICreateType_Struct(void)      ODK      DM     CS
// =====================================================================
// Desc.   :    Create Data Structure of type "REG"
//              REG( Wlanger(f), Xlanger(f), Ylanger(f), Zlanger(W)
//--------------------------------------------------------------------------------
void MyGAPICreateType_Struct()
{
//    #define PROJ_PATH "C:\\siemens\\odk\\samples\\projects\\demo\\odk.mcp"
    
    CMN_ERROR Error;
    BOOL ret = FALSE;
    TCHAR szText[255];

    DM_TYPE_DESCRIPTOR dmType;
    MCP_NEWVARIABLE_DATA_EX dmMembers[4];
    
    DWORD dwFlags = MCP_NVAR_FLAG_CREATE;
    DWORD dwCreID = 2500;
    
//    TCHAR szProjectPath[_MAX_PATH] = PROJ_PATH;

    memset(&Error, 0, sizeof(CMN_ERROR));
    memset(&dmMembers, 0, sizeof(MCP_NEWVARIABLE_DATA_EX) * 4);
    memset(&dmType, 0, sizeof(DM_TYPE_DESCRIPTOR));

    dmType.dmTypeRef.dwType = 14; // STRUCTURE
    dmType.dmTypeRef.dwSize =  0;
    dmType.dmType.dmStruct.dwNumMembers = 4;

    strcpy(dmMembers[0].szVarName, "Wlanger");
    strcpy(dmMembers[1].szVarName, "Xlanger");
    strcpy(dmMembers[2].szVarName, "Ylanger");
    strcpy(dmMembers[3].szVarName, "Zlanger");
    strcpy(dmType.dmTypeRef.szTypeName, "REG");

    ret = MyDMGetConnectionState(); 
    if(FALSE != ret)
    {
        MyDMEnumOpenedProjects(); // open the DM and set the g_szProjectFile
        for (int i = 0; i < 4; i++)
        {
            // 1. - 3. tag in WinCC: float
            if (i < 3)
            {
                dmMembers[i].Common.dwVarType    = DM_VARTYPE_FLOAT;
                dmMembers[i].Common.dwVarLength  = sizeof(DM_VARTYPE_FLOAT);
                dmMembers[i].Common.dwASOffset   = i * 4 * 16; // in Bits!!
                dmMembers[i].Limits.dSubstituteValue = (i + 1) * 2.5;
                dmMembers[i].Limits.dTopLimit    = (i + 1) * 7.5;
                dmMembers[i].Limits.dBottomLimit = (i + 1) * 5.0;
            }
            else
            {
                // 4. tag in WinCC: WORD
                dmMembers[i].Common.dwVarType   = DM_VARTYPE_WORD;
                dmMembers[i].Common.dwVarLength = sizeof(DM_VARTYPE_WORD);
                dmMembers[i].Common.dwASOffset  = i * 4 * 16;
            }
            // all tags are extern
            dmMembers[i].Common.dwVarProperty = DM_EXTERNAL_VAR;
            // formating ...
            switch (i)
            {
                case 0:
                {
                    dmMembers[i].Common.dwFormat = DM_VARTYPE_FLOAT * 0x01000000; // float
                    dmMembers[i].Common.dwFormat += 2079 * 0x010000;              // double
                    dmMembers[i].Common.dwFormat += 7;                            // float <-> double
                    break;
                }
                case 1:
                {
                    dmMembers[i].Common.dwFormat = DM_VARTYPE_FLOAT * 0x01000000; // float
                    dmMembers[i].Common.dwFormat += 2078 * 0x010000;              // float
                    dmMembers[i].Common.dwFormat += 0;                            // no conversion
                    break;
                }
                case 2:
                {
                    dmMembers[i].Common.dwFormat = DM_VARTYPE_FLOAT * 0x01000000; // float
                    dmMembers[i].Common.dwFormat += 2079 * 0x010000;              // double
                    dmMembers[i].Common.dwFormat += 7;                            // float <-> double
                    break;
                }
                case 3:
                {
                    dmMembers[i].Common.dwFormat = DM_VARTYPE_WORD * 0x01000000;  // short
                    dmMembers[i].Common.dwFormat += 1029 * 0x010000;              // SDWORD
                    dmMembers[i].Common.dwFormat += 5;                            // SDWORD <-> WORD
                    break;
                }
                default:
                {
                    break;
                }
            } // end switch
        } // end for

        memset(&Error, 0,sizeof( CMN_ERROR));
        ret = GAPICreateType(
            /*szProjectPath*/g_szProjectFile, 
            &dmType, dwFlags, 
            dwCreID, 
            dmMembers, 
            &Error);
        if(ret == FALSE )
        {
            sprintf(szText, "Error in GAPICreateType: E1= 0x%08lx ; E2= 0x%08lx ; %s",
                Error.dwError1, Error.dwError2, Error.szErrorText);
        }
        else
        {
            sprintf(szText,"GAPICreateType: %d",ret);
        }
        ODKTrace(szText);
        //printf("%s\r\n",szText);
    }
}
//{{ODK_EXAMPLE}(END)}

2 个解决方案

#1


自己顶一下先,不要大神没来,已经沉了

#2


在顶一下,就大神帮帮忙啊

#1


自己顶一下先,不要大神没来,已经沉了

#2


在顶一下,就大神帮帮忙啊