【问题标题】:parameters are changed after entering the function body [duplicate]进入函数体后更改参数[重复]
【发布时间】:2015-10-23 03:48:48
【问题描述】:

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

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; 它们的参数是一样的,如果我调用原来的函数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
 );

有什么问题?

【问题讨论】:

  • 显示minimal reproducible example 以消除对您的代码是什么的疑问
  • 尽管两个函数的参数相同,但您似乎认为这是问题所在。这没有任何意义。显然,它与函数的内容有关,出于某种奇怪的原因,您决定不包括在内。
  • @JonathanWood 我已经更新了代码,我的观点是参数的值在进入函数体之前是正确的,但是在进入函数体之前就变成了无意义的值,但是帖子中的代码是同样,我只是更改了底线的实现,在执行我更改的代码之前发生了异常。

标签: c# c++ pinvoke


【解决方案1】:

我们看不到所有的类型声明,所以我们只能相信翻译是正确的。除此之外,C# 代码的唯一错误是调用约定不匹配。非托管代码是__cdecl,但托管代码使用__stdcall。托管代码应该是:

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

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

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

【讨论】:

    猜你喜欢
    • 2016-06-28
    • 1970-01-01
    • 2015-11-22
    • 2017-06-20
    • 1970-01-01
    • 2013-05-11
    • 2021-03-22
    • 1970-01-01
    • 2020-12-13
    相关资源
    最近更新 更多