I have been trying for the past 4 hours to solve a very mysterious problem.
I am writing some plugin for Notepad++. To achieve syntax highlighting one has to export such a function:
//this function is exported via exports.def file
LexerFactoryFunction SCI_METHOD GetLexerFactory(unsigned int index)
{
return (index == 0) ? RTextLexer::LexerFactory : nullptr;
}
where,
LexerFactoryFunction is typedef ILexer *(*LexerFactoryFunction)();
#define SCI_METHOD __stdcall
I have managed to get this thing working perfectly with C++, however another part of the plugin is written in C#, so I tried to merge the two using Fody Costura NuGet package ( so that the CLI .dll is embedded into the main .dll ), however with no success.
What I've tried :
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();
}
This CLI wrapper, is referenced in my main .dll like this :
static RTextLexerCliWrapper _lexerWrapper = new RTextLexerCliWrapper();
[DllExport(CallingConvention = CallingConvention.Cdecl)]
static IntPtr GetLexerFactory(uint index)
{
return (index == 0) ? _lexerWrapper.GetLexerFactory() : IntPtr.Zero;
}
So what happens is, my .net function gets indeed called and the cli wrapper function is also called, and a function pointer is indeed returned. However any attempts to call that function pointer results in an access violation. Which means that either the type of the pointer is wrong or something else which I am currently missing. I have tried countless variations of the .net exported function with void *, StdCall etc. All result in the same problem.
Is there any other way to return a function pointer of a C++ class? Or well am I doing something completely wrong?
Thanks in advance!