简体   繁体   中英

c# marshaling output char* from c++ function

I created a dll using C++ and I want to use it in C# Here is the C++ function I want to use:

int get_value_of_field ( const int iObjectTag,
                         const char iAttName[],
                         char *oAttValue)
{
    int retcode = 0;
    char *AttValue = NULL;
    ITK (tc_custom_methods::get_value_of_field (iObjectTag, iAttName, &AttValue));
    if (retcode == 0) { sprintf(oAttValue, "%s", AttValue); }

    try { MEM_free(AttValue); }
    catch (exception e) { printf("MEM_free error\n%s\n", e.what()); }
    AttValue = NULL;
    return retcode;
}

I created this function in C#:

        [DllImport("tc_custom_caller.dll", EntryPoint = "get_value_of_field", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        private static extern int get_value_of_field(int iObjectTag,
                                                     [In, MarshalAs(UnmanagedType.LPStr)]string iAttName,
                                                     StringBuilder oAttValue);

        /*!
         * \brief Get value of field of an object
         * \param[in]  iObjectTag Tag of the object
         * \param[in]  iAttName Attribute name
         * \param[out] oAttValue Attribute value
         */
        public static void Get_Value_Of_Field(int iObjectTag, string iAttName, out string oAttValue)
        {
            int retcode = 0;
            StringBuilder sbValue = new StringBuilder();
            oAttValue = "";

            retcode = get_value_of_field(iObjectTag, iAttName, sbValue);
            if (retcode != 0) { throw new Exception("Error in get_value_of_field: " + Get_Error_Text(retcode)); }

            oAttValue = sbValue.ToString();
            sbValue = null;
        }

It works but after a lot of utilization of this function, the program crashes probably because of memory leak...

So could you tell me what is wrong with my code? Is there another way to manage the output of my C++ function?

Thanks in advance

I added StringBuilder sbValue = new StringBuilder(4096); in my C# function and I modified the C++ function (and the called function tc_custom_methods::get_value_of_field)

int get_value_of_field ( const int iObjectTag,
                         const string iAttName,
                         string oAttValue)
{
    int retcode = 0;
    ITK (tc_custom_methods::get_value_of_field (iObjectTag, iAttName, oAttValue));
    return retcode;
}

But now, I have an error for the call:

Exception thrown at 0x00007FFC6337C3B9 (msvcr110.dll) in TestTCTools.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

it seems that my input parameters are not passed from C# Do I have to modify the parameters of my C# function?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM