我一直在嘗試過去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