我一直在尝试过去4个小时解决一个非常神秘的问题。访问冲突导出非托管函数指针
我正在为Notepad ++写一些插件。为了实现语法高亮一个拥有出口这样的功能:
//this function is exported via exports.def file
LexerFactoryFunction SCI_METHOD GetLexerFactory(unsigned int index)
{
return (index == 0) ? RTextLexer::LexerFactory : nullptr;
}
其中,
LexerFactoryFunction is typedef ILexer *(*LexerFactoryFunction)();
#define SCI_METHOD __stdcall
我设法让这件事使用C完美的工作++,该插件的但是另一部分是用C# ,所以我尝试使用Fody Costura NuGet软件包合并这两个软件包(以便CLI .dll嵌入到主要的.dll文件中),但是没有成功。
我已经试过:
public ref class RTextLexerCliWrapper
{
public:
delegate ILexer * GetLexerFactoryDelegate();
IntPtr GetLexerFactory()
{
return System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(_lexerFactoryPtr);
}
RTextLexerCliWrapper();
private:
GetLexerFactoryDelegate^_lexerFactoryPtr;
GCHandle gch;
~RTextLexerCliWrapper();
};
RTextLexerCliWrapper::RTextLexerCliWrapper()
{
_lexerFactoryPtr = gcnew GetLexerFactoryDelegate(&RTextLexer::LexerFactory);
gch = GCHandle::Alloc(_lexerFactoryPtr);
}
RTextLexerCliWrapper::~RTextLexerCliWrapper()
{
gch.Free();
}
此CLI包装,在我的主要.dll文件引用这样的:
static RTextLexerCliWrapper _lexerWrapper = new RTextLexerCliWrapper();
[DllExport(CallingConvention = CallingConvention.Cdecl)]
static IntPtr GetLexerFactory(uint index)
{
return (index == 0) ? _lexerWrapper.GetLexerFactory() : IntPtr.Zero;
}
会发生什么时,我的.NET函数被称为确实并且cli包装函数也被调用,并且函数指针确实被返回。但是,任何尝试调用该函数指针都会导致访问冲突。这意味着指针的类型是错误的或者我目前丢失的其他东西。我已经尝试了无数的.net导出函数的变体void *, StdCall
等。所有的结果都是相同的问题。
是否有任何其他方式来返回一个C++类的函数指针?或者,我是否做了完全错误的事情?
在此先感谢!
这是一个完整的动物园,你把老虎放在猴屋里。 – 2015-03-30 23:18:19
@HansPassant它是这样,我不能更改API。 – FailedDev 2015-03-31 05:47:12