PVInvoke error..  
Author Message
John Wesley Harding





PostPosted: Visual C# Language, PVInvoke error.. Top

"A call to PInvoke function 'ResThemer!SPINE_RES.Resourcer::EnumResourceTypesA' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."

This is the error I get when using 'EnumResourceTypes' in kernel32.dll. The call uses a delegate the acts on a callback of a user-defined function, in this case I call 'EnumResourceNames' from within it. I have been trying for two days to translate what the MSDN Library shows you in Cpp but to no avail. Any help on how to do this would be great. The bottom line is that I want to be able to update my programs resources without having to re-compile each time. Once I can get the enumeration going I think I should be fine or at least on a better track.

Thanks alot...Here is the relevant code.

[DllImport("kernel32.dll", EntryPoint="EnumResourceTypes")]
public static extern Int32 EnumResourceTypesA(long hModule, EnumResTypeProc callback, long lParam);



[DllImport("kernel32.dll", EntryPoint="EnumResourceNames")]
public static extern Int32 EnumResourceNamesA(long hModule, long lpType, EnumResNameProc callback, long lParam);


public delegate bool EnumResTypeProc(long hModule, long lpType, long lParam);



public delegate bool EnumResNameProc(long hModule, long lpType, [MarshalAs(UnmanagedType.LPStr)] string lpName, long lParam);


......The above is stored in a class named 'Resourcer'.....belows code is in the forms class.....



bool EnumTypesFunc(long hModule, long lpType, long lParam)
{

Resourcer.EnumResourceNamesA(hModule, lpType, new Resourcer.EnumResNameProc(EnumNamesFunc), 0);
return true;
}


bool EnumNamesFunc(long hModule, long lpType, [MarshalAs(UnmanagedType.LPStr)] string lpName, long lParam)
{

StreamWriter sw = new StreamWriter(File.Open("C:\\EnumerateTypes.txt", FileMode.Create));
sw.WriteLine(lpName);
sw.Close();
return true;
}


long hModule;

void GetResources(string hMod_path)
{
hModule = Resourcer.LoadLibraryA(hMod_Name);

if (hModule != 0)
{
try
{

Resourcer.EnumResourceTypesA(hModule, new Resourcer.EnumResTypeProc(EnumTypesFunc), 0);

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

}
}





Again, any helps would be greath, Thanks.

JWH


Visual C#10  
 
 
John Wesley Harding





PostPosted: Visual C# Language, PVInvoke error.. Top

Please, please help. I only need to know how to safely call these without errors arrising, the actual procedures I can do just the implementation.

 
 
SvenC





PostPosted: Visual C# Language, PVInvoke error.. Top

I guess the delegates cannot be passed directly to Win32 functions. Try Marshal.GetFunctionPointerForDelegate to get a native function pointer, which you pass instead.

--
SvenC


 
 
Peter Ritchie





PostPosted: Visual C# Language, PVInvoke error.. Top

"long" in Win32/PlatformSDK is 32-bits. "long" in C# is 64-bits. change your DllImports replacing "long" with "int32".

 
 
John Wesley Harding





PostPosted: Visual C# Language, PVInvoke error.. Top

okay, so now i have....


[DllImport("kernel32.dll", EntryPoint="EnumResourceNames")]
public static extern Int32 EnumResourceNamesA(Int32 hModule, Int32 lpType, EnumResNameProc callback, Int32 lParam);

public delegate bool EnumResNameProc(Int32 hModule, Int32 lpType, [MarshalAs(UnmanagedType.LPStr)] string lpName, Int32 lParam);

in a seperate class as before and the the following in the form....


bool EnumNamesFunc(Int32 hModule, Int32 lpType, [MarshalAs(UnmanagedType.LPStr)] string lpName, Int32 lParam)
{

StreamWriter sw = new StreamWriter(File.Open("C:\\EnumerateTypes.txt", FileMode.Create));
sw.WriteLine(lpName);
sw.Close();
return true;
}



void GetResources(string hMod_Name)
{

hModule = Resourcer.LoadLibraryA(hMod_Name);

Resourcer.EnumResourceNamesA(hModule, Resourcer.RT_BITMAP, new Resourcer.EnumResNameProc(EnumNamesFunc), 0);


}


And it doesnt do anything at all.

Any more pointers


 
 
Peter Ritchie





PostPosted: Visual C# Language, PVInvoke error.. Top

Do you know if the binary you're looking for bitmaps in has any bitmaps in it If it doesn't, EnumResourceNames will return false and your delegate will never get called.

Also, the lpName parameter of the EnumResourceProc will not always contain a pointer to a string, it may contain an integer (less or equal to 0xFFFF). Marshaling that integer to a string won't result in anything good.

Also, .NET is strictly Unicode. You'll want to use EnumResourceNamesW not EnumResourceNamesA, e.g.:

[DllImport("kernel32.dll", EntryPoint = "EnumResourceNamesW",

CharSet = CharSet.Unicode, SetLastError = true)]

static extern bool EnumResourceNames (

IntPtr hModule,

uint lpszType,

EnumResNameDelegate lpEnumFunc,

IntPtr lParam );