views:

559

answers:

4

In a smart device project I'm trying to Pinvoke a function that should supposedly be available in mscoree.dll. The associated definition is as follows:

[DllImport("mscoree.dll", EntryPoint = "#29")]
internal static extern int Object_GetHashCode(object obj);

You'll find this with Reflector in the internal class EE in mscorlib.dll. Note that this function is called from Object.GetHashCode().

I have a smart device test project that indirectly invokes Object_GetHashCode. When I run it on the desktop everything works fine. When I run it on an emulator, then I get the following error:

System.MissingMethodException: Can't find an Entry Point '#29' in a PInvoke DLL 'mscoree.dll'.

Why does this happen? Doesn't exactly the same mscorlib.dll run on the emulator and on the desktop? It seems so because when I look at the implementation of Object.GetHashCode() that comes with mscorlib.dll distributed inside the NETCFv35.ppc.armv4.cab then I see that it also calls EE.Object_GetHashCode(). Why can mscorlib.dll call into mscoree.dll and I can't?

EDIT:

The mscorlib reference in the Visual Studio project points to the following file,

C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\mscorlib.dll (210kB)

but by default Reflector shows the contents of the following file:

C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\Debugger\BCL\mscorlib.dll (920kB)

These files have different implementations for System.Object.GetHashCode(). The former is simply empty while the latter looks as follows:

public virtual int GetHashCode()
{
    return EE.Object_GetHashCode(this);
}

In fact all methods in the former file seem to be empty and the much smaller size seems to hint into the direction that the former file is just a placeholder, so that VS can reference something?

Lastly, I tried to find mscorlib.dll in the files on the emulator but failed. The Installer log file says the install location is \Windows but there's no mscorlib.dll anywhere. Where is this stuff?

In general, I have a hard time Googling for answers when it comes to the CF, not sure why?

P.S. I'm trying to find an answer to the this question.

A: 

In Windows CE devices Win32 functions aren't necessarily in the same dll files as their desktop equivalents. Most of the functions are located in coredll.dll. Try this one first. If it doesn't work you need to find the name of the dll in a Windows CE device. MSDN can be useful. Also try the documentation for Platform Builder.

kgiannakakis
Object_GetHashCode isn't really a Win32 function, right? It's part of the .NET compact framework (mscoree.dll). Again, how can mscorlib.dll (which is apparently a part of the CF installed on the device) reference and call EE.Object_GetHashCode() and I can't? Am I looking at the wrong files?
Andreas Huber
+1  A: 

You simply cannot make some assumption that the entry points would ever be at the same ordinal. In fact it's unwise to assume they will remain the same across versions of the same DLL even on the same platform (meaning that calling to ordinal 29 on the desktop may work in theis version, but the function your after could easily move in the next build when it gets recompiled and linked). Calling by ordinal is way, way, way fragile and risky.

ctacke
I agree, but it seemed like the only way that I could hack around the problem (see the question linked in the P.S.). Do you have a suggestion how I could avoid that?
Andreas Huber
A: 

Can I ask a stupid question? Why are you trying to P/Invoke Object.GetHashCode()? If I have an object of type Object I can call the method directly from managed code, no P/Invoke necessary.

CBono
I absolutely need to call the implementation of Object.GetHashCode() under **all** circumstances. That is, even if I have an object of a class, which itself overrides GetHashCode() (e.g. String).
Andreas Huber
Meaning, you need to call the base Object.GetHashCode() of an object, not its class-specific override? (Sorry if I'm being dense).So... you can't simply cast an object to Object and call GetHashCode that way?
CBono
"you need to call the base Object.GetHashCode() of an object, not its class-specific override?"Exactly. Casting to Object wouldn't work as GetHashCode is virtual.
Andreas Huber
A: 

Have you tried examining the DLL using Dependency Walker? At the very least this should allow you to replace "#29" with the name for the function.

Compholio