进入函数体后,参数会发生变化

时间:2015-10-23 03:48:49

标签: c# c++ pinvoke

我在我的C ++项目中创建了两个函数,一个是orignal函数:

CLIB_ENUM CLIB_CreateDeviceLinkFile(
CLIB_C_WCHAR*  pSrcProfile,    
CLIB_C_WCHAR*  pDstProfile,    
CLIB_C_WCHAR*  pDvlProfile,   
CLIB_ENUM      rend_intent )
{ CLIB_ErrorCode rc = CLIB_SUCCESSFUL;

CLIB_Intent intent = static_cast<CLIB_Intent>( rend_intent );

// Verify that the input parameters.
if( pSrcProfile == 0 || wcslen( pSrcProfile ) == 0 )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid source profile path" );
    rc = CLIB_INVALID_PARAMETER;
}
else if( pDstProfile == 0 || wcslen( pDstProfile ) == 0 )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid destination profile path" );
    rc = CLIB_INVALID_PARAMETER;
}
else if( pDvlProfile == 0 || wcslen( pDvlProfile ) == 0 )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid device-link path" );
    rc = CLIB_INVALID_PARAMETER;
}
else if( intent != CLIB_PERCEPTUAL &&
         intent != CLIB_RELATIVE_COLORIMETRIC &&
         intent != CLIB_SATURATION &&
         intent != CLIB_ABSOLUTE_COLORIMETRIC )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid rendering intent" );
    rc = CLIB_INVALID_PARAMETER;
}

if( rc == CLIB_SUCCESSFUL )
{
    try
    {
        // Create file specs for the profiles.
        GFIL_FileSpec srcProfileSpec( GFIL_SpecFromPlatformPath( GLIB_WString( pSrcProfile ) ) );
        GFIL_FileSpec dstProfileSpec( GFIL_SpecFromPlatformPath( GLIB_WString( pDstProfile ) ) );
        GFIL_FileSpec dvlProfileSpec( GFIL_SpecFromPlatformPath( GLIB_WString( pDvlProfile ) ) );

        // Create the device link file
        rc = CLIB_CreateDeviceLinkFilePriv( srcProfileSpec,
                                            dstProfileSpec,
                                            dvlProfileSpec,
                                            iCLIB_ConvertIntent( intent ) );
    }
    catch( const GLIB_Exception& ex )
    {
        GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - error creating device link file: " << ex );
        rc = CLIB_UKNOWN_ERROR;
    }
}

return static_cast<CLIB_ENUM>( rc );}

另一个是我的新功能:

CLIB_ENUM CLIB_CreateDeviceLinkFileCEV2(
CLIB_C_WCHAR*  pSrcProfile, 
CLIB_C_WCHAR*  pDstProfile, 
CLIB_C_WCHAR*  pDvlProfile, 
CLIB_ENUM      rend_intent ){
CLIB_ErrorCode rc = CLIB_SUCCESSFUL;

CLIB_Intent intent = static_cast<CLIB_Intent>( rend_intent );

// Verify that the input parameters.
if( pSrcProfile == 0 || wcslen( pSrcProfile ) == 0 )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid source profile path" );
    rc = CLIB_INVALID_PARAMETER;
}
else if( pDstProfile == 0 || wcslen( pDstProfile ) == 0 )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid destination profile path" );
    rc = CLIB_INVALID_PARAMETER;
}
else if( pDvlProfile == 0 || wcslen( pDvlProfile ) == 0 )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid device-link path" );
    rc = CLIB_INVALID_PARAMETER;
}
else if( intent != CLIB_PERCEPTUAL &&
         intent != CLIB_RELATIVE_COLORIMETRIC &&
         intent != CLIB_SATURATION &&
         intent != CLIB_ABSOLUTE_COLORIMETRIC )
{
    GLIB_NLOG_ERROR( "CLIB_CreateDeviceLinkFile - invalid rendering intent" );
    rc = CLIB_INVALID_PARAMETER;
}


if( rc == CLIB_SUCCESSFUL ){
    ProfileUtil util;
    bool bDoBPC =false;
    int rendIntent = 0;
    int iLinkTypeReq = 0; // init to dynamic
    int iLinkTypeReturned = 0;
    int iLinkTypeExpected = 1;
    StringUtils strUtil;
    string strSrcProfile=strUtil.WcharToChar(pSrcProfile);
    string strDstProfile=strUtil.WcharToChar(pDstProfile);
    string strDvlProfile=strUtil.WcharToChar(pDvlProfile);

    CEError error=util.CreateDVL( true, bDoBPC, rend_intent, iLinkTypeReq, iLinkTypeReturned, strSrcProfile, strDstProfile, strDvlProfile );
    switch(error){
        case CEErr_none:{
            rc = CLIB_SUCCESSFUL;       
        };break;
        case CEErr_badParam:{
            rc=CLIB_INVALID_PARAMETER;          
        };break;
        case CEErr_ICC_InvalidTagType:{
            rc=CLIB_TAG_UNDEFINED;          
        };break;
        case CEErr_ICC_TagNotFound:{
            rc=CLIB_TAG_UNDEFINED;              
        };break;
        case CEErr_unknown:{
            rc=CLIB_UKNOWN_ERROR;   
        };break;
        default:{
            rc=CLIB_UKNOWN_ERROR;
            }
    }
}

return static_cast<CLIB_ENUM>( rc ); }

字符串的定义:typedef const wchar_t CLIB_C_WCHAR; 它们的参数是相同的,如果我调用orignal函数CLIB_CreateDeviceLinkFile,程序运行良好,但如果我调用CLIB_CreateDeviceLinkFileCEV2错误发生:

  

尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

然后我对它进行了调试,发现传入函数的参数在进入函数体后发生了变化,但没有执行任何操作,只需输入函数! 顺便说一句,我通过C#调用了函数,我可以确保C#将正确的字符串传递给Cpp函数,并且函数在开始时接收正确的函数:

[DllImport("xxx.dll", SetLastError = true, CharSet = CharSet.Unicode)]

private static extern int CLIB_CreateDeviceLinkFile
(
    string strSrcPath,
    string strDstPath,
    string strOutPath,
    int intent
);

 /// <summary>
 /// ColorEngine v2 
 /// </summary>
 /// <param name="strSrcPath"></param>
 /// <param name="strDstPath"></param>
 /// <param name="strOutPath"></param>
 /// <param name="intent"></param>
 /// <returns></returns>
 [DllImport("xxx.dll", SetLastError = true, CharSet = CharSet.Unicode)]
 private static extern int CLIB_CreateDeviceLinkFileCEV2
 (
     string strSrcPath,
     string strDstPath,
     string strOutPath,
     int intent
 );

有什么问题?

1 个答案:

答案 0 :(得分:0)

我们无法看到所有类型声明,因此我们只能说出翻译是正确的。除此之外,C#代码唯一不对的是调用约定不匹配。非托管代码为__cdecl,但托管代码使用__stdcall。托管代码应为:

[DllImport("...", CallingConvenction = CallingConvenction.Cdecl, 
    CharSet = CharSet.Unicode)]

另请注意,您对SetLastError的使用不正确,因此我已将其删除。

如果事实证明您未显示的代码中的其他内容意味着调用约定匹配,那么课程就是显示MCVE。如果结果是代码中存在我们看不到的问题,那么课程就是显示MCVE