I use a third-party, proprietary DLL for which the source code is not available to me. However, the Wrapper code is available to me, which seems to have been automatically generated using SWIG 1.3.39. The shell code consists of a C ++ file that compiles (using some headers describing the DLL) into a DLL and a C # project that calls PInvoke calls to the C ++ DLL shell.
In my interpretation of the vendor documentation, I compiled everything in the solution as x86 or x64, depending on the target platform. The provider provides both 32-bit and 64-bit versions of its own DLL, and I ensured that I am using the correct one for this assembly. My car is 32 bit. Testing the x86 version of my application on my machine, both in releases and in debug builds, seems to work fine. However, in the 64-bit version, the application runs in debug mode, but with a System.AccessViolationException disabled in Release mode, it does not work.
I read this nice blog post that seems to describe the debugging and release issue well, as well as this question and answer that led to the blog post. However, I am not sure how to fix the problem in this case.
It seems that an AccessViolationException occurs the first time a string of any real length is returned (or is trying to be returned) from a C ++ shell. Here is the abusive C # code:
// In one file of the C# wrapper: public string GetKey() { // swigCPtr is a HandleRef to an object already created string ret = csWrapperPINVOKE.mdMUHybrid_GetKey(swigCPtr); return ret; } // In the csWrapperPINVOKE class in another file in the C# wrapper: [DllImport("csWrapper.dll", EntryPoint="CSharp_mdMUHybrid_GetKey")] public static extern StringBuilder mdMUHybrid_GetKey(HandleRef jarg1);
And the nasty C ++ code from the C ++ shell:
SWIGEXPORT char * SWIGSTDCALL CSharp_mdMUHybrid_GetKey(void * jarg1) { char * jresult ; mdMUHybrid *arg1 = (mdMUHybrid *) 0 ; char *result = 0 ; arg1 = (mdMUHybrid *)jarg1; result = (char *)(arg1)->GetKey(); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; }
SWIGEXPORT has already been defined as __declspec(dllexport) . In debugging, I found that SWIG_csharp_string_callback , defined as:
/* Callback for returning strings to C# without leaking memory */ typedef char * (SWIGSTDCALL* SWIG_CSharpStringHelperCallback)(const char *); static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback = NULL;
was set to the delegate (in a C # wrapper):
static string CreateString(string cString) { return cString; }
I tried messing up this code to use constructs like Marshal.PtrToStringAut to no avail. How to fix and / or fix this problem?