I'm loading a MFC dll with dependencies (let's say I'm loading D.dll, which depends on C.dll, B.dll and A.dll) in C#.
Here's my code:
[DllImport( "kernel32.dll", CharSet = CharSet.Auto, SetLastError = true )]
static extern IntPtr LoadLibrary( string lpFileName );
private void btn_Click( object sender, EventArgs e )
{
int nUltErr;
string strDLL;
StringBuilder strPDF;
StringBuilder strXML;
strDLL = "C:\\DEVELOP\\Libs\\Interfaccia\\Interfaccia_C_2005\\DLL\\Interfaccia_C_2005.dll";
strFile1 = new StringBuilder( @"C:\DEVELOP\Libs\Interfaccia\TestCase\PROGRAM\tiger.pdf" );
strFile2 = new StringBuilder( @"C:\DEVELOP\Libs\Interfaccia\TestCase\PROGRAM\tiger.XML" );
if( LoadLibrary( strDLL ) != IntPtr.Zero )
{
LoadPDF( strPDF );
SaveXML( strXML );
ClosePDF();
FreeMemory();
}
else
{
nUltErr = Marshal.GetLastWin32Error();
MessageBox.Show( "Errore nel caricamento della dll." );
}
}
nUltErr is 1008 = 0x3F0, that should be ERROR_NO_TOKEN.
What does exactly mean this in C#?
Path to DLL IS right.
The code ERROR_NO_TOKEN
generally means that someone has attempted to call OpenThreadToken
on a thread that was not impersonating. This may be a problem or not a problem - that's just the last error code to be recorded by SetlastError
.
This call could be in the DllMain
of Interfaccia_C_2005.dll
, or in the DllMain
of any library which is referenced in turn. It is not entirely obvious why they would need to do that but it is possible.
Also, this may not be the actual error causing failure. Among other causes, LoadLibrary
will fail if the DllMain
of Interfaccia_C_2005.dll
, or in the DllMain
of any library which is referenced in turn, returns false. If the DllMain returns false, without calling SetLastError
, GetLastError will show the previous error, whatever it was. For example the system might be quite happy for OpenThreadToken
to fail, but something else has gone wrong, which did not call SetLastError
.
Essentially you need to fire up the Native Code debugger, and see what that tells you.
You have not set the SetLastError
field on your DllImport
attribute.
This means you are not getting the correct value from Marshal.GetLastWin32Error()
.
Change LoadLibrary to this:
[DllImport( "kernel32.dll", CharSet = CharSet.Auto, SetLastError = true )]
static extern IntPtr LoadLibrary( string lpFileName );