2013-04-25 34 views
3

我正在使用RGiesecke DLLExport库来生成可以从构建于VC6上的旧应用程序中动态加载的C#DLL。它导出方法,并从VC6代码中调用它们。没问题。但是,只要我试图声明一个变量作为我的.NET类中的任何一个,它就会崩溃。非托管导出(DLLExport)崩溃

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

怎么了?请帮忙。

回答

2

我有一个类似的问题,试图在Metatrader中使用非托管导出来加载相关的托管dll。

经过一番挖掘,我想我已经找到了问题。应用程序领域可能不是你期望的那样,CLR正试图解决你的程序集,但是因为一个不起眼的错误而失败。在我的情况下,应用程序域实际上是在主机应用程序的目录中执行的,所以我认为情况总是如此。

我会建议你做的是建立在一些不依赖裸DLL和地点如下所示:

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

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

我不知道,但我想你可能不能在这里使用一个静态构造函数?

在日志中,您应该看到该域的执行目录。如果你把你的装配在这里(希望)应该可以工作。它已经为我解决了这个问题。我想下一个问题是我们可以在运行时更改域,因为我可能不想在这里放置这些程序集。

有一个谷歌,如果你需要一个简单的记录器的源代码 - 显然不要使用与DLL依赖关系的第三方日志记录框架!

我认为我是这样的一个改编: http://www.codeproject.com/Articles/80175/Really-Simple-Log-Writer

0

由于对方回答说,这是很难知道C#是没有每个方法中明确地捕捉错误在try/catch块抛出了什么错误的C#DLL。

您可能需要导出为CallingConvention.StdCall和另外元帅传入字符串作为一个非托管LPWSTR类型:

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

请参阅Code to Export C# DLL to Metatrader Build 600+使用罗伯特捷的C#项目模板的托管输出导出工作示例传统应用程序(MT4)的C#dll。

此外,您可能会发现Native and .NET Interopability有趣,虽然它主要是为了从.NET中访问本机代码。