invalid access to memory location - managed to unmanaged code

4

I have this code in c++ which I exported by a dll:

typedef struct {
unsigned short major;
unsigned short minor;
} Version;

EXPORTED_FUNC Result Init(Version *version, char *file);

extern "C" Result Init(Version *version, char *file)
{
    if (file) {
    if (!GFile.init(string(file))) {
        return INVALID_PARAMETER;
    }
    if (version) {
        version->major = VERSION_MAJOR1;
        version->minor = VERSION_MAJOR2;
    }

      return OK;
}

I'm calling the dll from c#, and this is what I wrote there:

internal struct Version
{
    ushort major { set; get; }
    ushort minor { set; get; }
}

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)]
    static extern Result Init(ref Version versionInfo, [MarshalAs`(UnmanagedType.LPStr)] string FilePath);

and this is the call for Init:

string filePath = Application.StartupPath + "\\ABC.ini";
Version version = new Version();

 result = _mydllWrapper.Init(ref version, filePath);

for the all the above code when I'm running the c# application I sometimes get in x64 machines the following exception:

Unable to load DLL mydll.dll : invalid access to memory location (Exception from HRESULT.0x800703E6)

How can I fix this code WITHOUT removing any security flags from compilation? code sample for the fix is really wellcome!

thanks!

c#
c++
memory-management
64-bit
unmanaged-memory
asked on Stack Overflow Dec 24, 2012 by gln

1 Answer

1

The question is, unfortunately, missing some information, but I've only seen that error when you have the build outputs incorrect. It would only happen "occasionally" because you might occasionally delete the output directory for the .Net exe, then do a build, then, after the problem arises, you copy the newly built binary from the native output directory, and then move on.

To solve the problem, you should make sure that you've got properly matched target CPU types between your .NET code & your native code. If you're only running on an x64 machine, you can just use AnyCPU, but I'd recommend, since you're calling native code, that you just go ahead & set the CPU to your target, be it x64, x86 (Win32 in C++ parlance) or ARM. One other alternative that works with VS2012 is the "32-bit preferred" target, which is there to allow you to run as x86 on a x64 device, but will also work fine on an ARM device.

Anyway, once you've ensured that your configurations are correct, check to ensure that your output directories are setup properly to drop both the .NET exe and the C++ dll into the same output directory. Note that output directories are specific to each build/architecture combination.

answered on Stack Overflow Jan 7, 2013 by Kevin Frei

User contributions licensed under CC BY-SA 3.0