-1

I have create two functions in my C++ project, one is orignal function:

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

and another is my new function:

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

The definition of the string:typedef const wchar_t CLIB_C_WCHAR; Their parameters are the same, If I call the orignal function CLIB_CreateDeviceLinkFile the program works well, but If I call CLIB_CreateDeviceLinkFileCEV2 error occured:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Then I debuged it and find that the parameters passed to the function changed after entering the function body, but nothing is executed, just entering the function! By the way, I called the function through C#, I can make sure the C# passed correct string to Cpp function and the functions recevies correct ones at the beginning:

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

What's the problem?

Darren
  • 1
  • 1
  • Show a [mcve] to remove doubt as to what your code is – David Heffernan Oct 23 '15 at 03:52
  • 1
    Even though the arguments are the same for both functions, you seem to think that is the issue. That doesn't make any sense. Apparently, it has to do with the contents of the function, which for some odd reason you decided not to include. – Jonathan Wood Oct 23 '15 at 03:56
  • @JonathanWood I have updated the code, my point is that the value of the parameters are correct before entering the function body but changed to meaningless values just entering the body, everyting but the code in the post are the same, I just changed the implement of the bottom lines, exception just occured before executing the code I changed. – Darren Oct 23 '15 at 05:45

1 Answers1

0

We can't see all the type declarations, so we can only take your word that the translations are correct. Beyond that, the only thing wrong with the C# code is that the calling conventions do not match. The unmanaged code is __cdecl, but the managed code uses __stdcall. The managed code should be:

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

Note also that your use of SetLastError was incorrect, and so I have removed it.

If it turns out that something else in your code that you did not show means that the calling conventions match, then the lesson is to show an MCVE. If it turns out that there are problems in the code that we cannot see, then the lesson is to show an MCVE.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490