简体   繁体   中英

Unmanaged Exports (DLLExport) crashes

I'm using RGiesecke DLLExport library to produce a C# DLL that can be dynamically loaded from legacy application built on VC6. It exported methods and they were called from VC6 code. No problems. However, as long as I tried to declare a variable as of any one of my .net classes, it crashed.

    //I tried CallingConvention = CallingConvention.StdCall too
    [DllExport(CallingConvention = CallingConvention.Winapi)]
    static void GetDwgReferences(string fileName)
    {
        //OK: inialize System classes of .net
        DateTime dateTime = DateTime.Now;

        //crashing here: declare a variable of my static class (.net assemebly)
        //SafeString safeString;

        //crashing here: declare a variable of my class (.net assemebly)
        //Email email;

        //crashing here: initialize an object of my class (.net assemebly)
        //DwgXrefs dwgXrefs = new DwgXrefs();

        //crashing here by declcare a variable of third-party library (.net assemebly)
        //ExSystemServices _serv;
     }

What's wrong? Please help.

I had a similar problem here trying to use unmanaged exports with Metatrader to load associated managed dlls.

After some digging I think I have found the problem. The app domain is probably not where you would expect it to be, the CLR is trying to resolve your assembly but failing with a nondescript error. In my case the app domain was actually executing in the directory of the host application, so I assume this is always the case.

What I would suggest you do is build a bare dll with no dependencies, and place in something such as the following:

static void Initialize()
{
        SimpleLog.WriteLog("App -" + AppDomain.CurrentDomain.BaseDirectory);
}

[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
public static void Test()
{
    Initialize();
}

I am not sure but I think you possibly cannot use a static constructor here?

In the log you should see the executing directory for that domain. If you put your assemblies here it (hopefully) should work. It has fixed the problem for me here. I guess the next question is can we change the domain at runtime as I might not want to put these assemblies here.

Have a google if you need the source code for a simple logger - obviously do not use a third party logging framework with dll dependencies!

I think mine is an adaptation of this one: http://www.codeproject.com/Articles/80175/Really-Simple-Log-Writer

As the other answer stated, it is difficult to know what error C# is throwing without explicitly catching the error in a try / catch block within each method of a C# dll.

You likely need to export as CallingConvention.StdCall and additionally marshal the incoming string as an unmanaged LPWStr type:

[DllExport(CallingConvention = CallingConvention.StdCall)]
static void GetDwgReferences([MarshalAs(UnmanagedType.LPWStr)] string fileName)
{
}

Please see Code to Export C# DLL to Metatrader Build 600+ for a working example using Robert Giesecke's C# Project Template for Unmanaged Exports to export a C# dll to a legacy application (MT4).

Additionally, you might find Native and .NET Interopability interesting though it is mostly geared toward accessing native code from within .NET.

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