pinvoke to clutter function - c#

I'm trying to pinvoke to a clutter function.
The function is defined in the docs as
ClutterActor * clutter_texture_new_from_file (const gchar *filename, GError **error);
The code I have is as follows:
[DllImport ("libclutter-glx-1.0.so.0")]
private static extern IntPtr clutter_texture_new_from_file (string filename, IntPtr errorData);
And I call it like this:
IntPtr texture = clutter_texture_new_from_file("myImage.jpeg",IntPtr.Zero);
however when called like this in monodevelop on ubuntu I get the following error.
Unix Transport Error
Eventally I would like to get the error reporting working so I can get the gerror result however firstly I need to get past the Unix Transport Error.

The errorData parameter should be marked as "ref IntPtr", although I don't think that should be causing this error since that parameter should be allowed to be NULL. Otherwise, try running this outside Monodevelop. This kind of error may be the result of a segfault elsewhere in your program.

Related

Get computer name via WSOCK32.DLL in C#

I am migrating some VB6 code to C# (.NET 4.5.2) and got stuck into a piece of code that is calling the gethostname method from the WSOCK32.DLL to apparently retrieve the computer name. All the code samples that I have found so far point to
this code. And since I haven't been able to successfully PInvoke the gethostname method in C#, I can't help asking if is there an alternative to it.
This
[DllImport("WSOCK32.DLL", SetLastError = true)]
internal static extern long gethostname(string name, int nameLen);
string host = string.Empty;
var res = gethostname(host, 256);
fails with the following error:
The runtime has encountered a fatal error. The address of the error was at 0x6a13a84e, on thread 0xd88. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
I also read about using System.Environment.MachineName or the "COMPUTERNAME" environment variable, but I am interested in how the result differs than what gethostname method returns.
What options do I have?
I am developing on a 64bit system but I don't know if/how this affects working with WSOCK32.DLL since I found no documentation about it.
You cannot send an zero-length immutable C# string and expect it to get turned into something new. You are probably experiencing a buffer overflow. You need to use a StringBuilder instead:
[DllImport("WSOCK32.DLL", SetLastError = true)]
internal static extern long gethostname(StringBuilder name, int nameLen);
var builder = new StringBuilder(256);
var res = gethostname(builder, 256);
string host = builder.ToString();
More info here:
Passing StringBuilder to PInvoke function
C# PInvoke out strings declaration
http://pinvoke.net/default.aspx/ws2_32/gethostname.html
Also, there is really no reason for using that really old DLL function to get the name of the local computer. Just use System.Environment.MachineName instead.

Calling c++ DLL from C# Program, unhandled exception

I've done a lot of searching and testing and I've been unable to get this to work correctly.
I'm using MVS Express 2013, compiling a c++ win32 DLL that I hope to call from a c# GUI.
On the C++ Side of things, I have a function that I've exported, and it gets passed a struct. The struct originally contained two strings but it seems easier to pass a char array of known size.
C++ Code:
struct runDetails{
char requestedRuntype[32];
char filename[32];
};
void __declspec(dllexport) WindowRecreatorCall(runDetails* incomingRunRequests);
c# Code:
Attempting to recreate the Struct to pass in:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
public struct runDetails{
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 32)]
public string requestedRuntype;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 32)]
public string filename;
};
Set up the Dynamic DLL Wrapper:
class CallWindowRecreator
{
[DllImport("WindowRecreatorDLL.dll", EntryPoint = "WindowRecreatorCall", CharSet = CharSet.Unicode)]
public static extern void WindowRecreatorCall(ref runDetails runDetails);
};
Actual Call to the DLL:
runDetails testing;
testing.requestedRuntype = "Minimize";
testing.filename = "";
CallWindowRecreator.WindowRecreatorCall(ref testing);
As it is right now, I get this error when I attempt the DLL call:
An unhandled exception of type 'System.BadImageFormatException' occurred in WindowRecreatorGUI.exe
Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
I've done a lot of googling and code changing and I've learned a lot but I just can't figure this one out. Any tips would be greatly appreciated.
Edit: Changed the code and error recieved
Edit 2: I've changed the C# program from Any CPU to x86 specifically, and now I get this error:
An unhandled exception of type 'System.EntryPointNotFoundException' occurred in WindowRecreatorGUI.exe
Additional information: Unable to find an entry point named 'WindowRecreatorCall' in DLL 'WindowRecreatorDLL.dll'.
And Edit 3 before bed:
I've added an extern c{} around the c++ function. Now I get this error:
Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Users\Tom\workspace\WindowRecreatorGUI\WindowRecreatorGUI\bin\x86\Debug\WindowRecreatorGUI.vshost.exe'.
Additional information: A call to PInvoke function 'WindowRecreatorGUI!WindowRecreatorGUI.CallWindowRecreator::WindowRecreatorCall' 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.
Your native method takes a pointer to the struct.
In C#, that becomes a ref parameter:
[DllImport("WindowRecreatorDLL.dll", EntryPoint = "WindowRecreatorCall", CharSet = CharSet.Unicode)]
public static extern void WindowRecreatorCall(ref runDetails runDetails);
You also need to pass the correct CallingConvention in the attribute, which is probably Cdecl.

pinvoke return a float

have been working on this for hours, couldn't get it work :(
below code gives exception "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." this is fixed, see below update
but when i change the return type to int and return a int value, it works. how to make it to return a float value? thanks.
vs2012
c++ code
extern "C" __declspec(dllexport)
float compute_similarity()
{
return 1.01;
}
c# code
[DllImport("demo.exe", EntryPoint = "compute_similarity", CallingConvention = CallingConvention.Cdecl)]
public static extern float compute_similarity();
public void Get()
{
float x = compute_similarity(); // here returns random value
}
=====================================
UPDATE
See comments from David below, the problem was the c# project is targeting x64 and c++ is targeting Win32. After changing the c# project to target to x86, the exception went away.
However the call from c# returns some random value instead of 1.01 expected
I think your problem is that your function is declared in an executable rather than a DLL. Convert your native code into a library project and compile a DLL.
Your code will result in a call to LoadLibrary passing the file name demo.exe. The documentation for LoadLibrary says:
LoadLibrary can also be used to load other executable modules. For example, the function can specify an .exe file to get a handle that can be used in FindResource or LoadResource. However, do not use LoadLibrary to run an .exe file. Instead, use the CreateProcess function.
And so your code is doing exactly what you are told not to do. The call to LoadLibrary will succeed. The subsequent calls to GetProcAddress will succeed. But the module that you loaded is not fit to execute code.

ShSetFolderPath works on win7, doesn't on XP

I'm trying to use ShSetFolderPath function in C#. I work on Win7, I've managed to use ShSetKnownFolderPath and it works fine.
Since this function is unavaible in WinXP, i tried to invoke ShSetFolderPath. Because i'm not familiar with invoking, I've done some searching and found something on some French forum. I don't speak French, but this declaration makes sense (as written in Remarks of function documentation in MSDN library):
[DllImport( "Shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "#232" ) ]
private static extern int SHSetFolderPath( int csidl, IntPtr hToken, uint flags, string path );
I call it like that:
private static int CSIDL_DESKTOP = 0x0000;
public static void SetDesktopPath(string path)
{
int ret;
ret = SHSetFolderPath(CSIDL_DESKTOP, IntPtr.Zero, 0, path);
if (ret != 0)
{
Console.WriteLine(ret);
Console.WriteLine(Marshal.GetExceptionForHR(ret));
}
}
It works in Win7, but in XP function returns -2147024809, which means "Value does not fall within the expected range".
My guess is, it's something wrong with Dll importing. Any idea?
Funny thing.
I've taken another look at CSIDL list. And I've realized I was trying to change some "low-level" reference (i guess) to desktop:
CSIDL_DESKTOP = 0x0000, // <desktop>
While I actually wanted to change just folder location, and i should've use this:
CSIDL_DESKTOPDIRECTORY = 0x0010, // <user name>\Desktop.
And THIS works.
It explains everything. Shame on me.
Nah, that's not it. The error code, converted to hex, is 0x80070057. The 7 indicates a Windows error, 57 is error code 87, ERROR_INVALID_PARAMETER, "The parameter is incorrect".
A couple of possible reasons. First is that entry point #232 isn't actually the entry point for SHSetFolderPath(). You might be calling a different function, it wouldn't know what to do with the argument values you pass. Hard to say, it is an unnamed entry point on XP's version of shell32.dll. Or it could be that XP just isn't happy about you changing the desktop folder path. Not that surprising, there's a heckofalot it has to do to actually implement that, refreshing all Explorer.exe views, rebuilding the desktop contents and whatnot.
Check this thread for possible help.

Unable to find an entry point named 'GetProcessID' in DLL 'kernel32.dll'

Hi im trying to get a processID out of a process handle using the WINAPI 'GetProcessID' but i am getting the following error...
Unable to find an entry point named 'GetProcessID' in DLL 'kernel32.dll'.
Checking MSDN i cant see where i have gone wrong..
Your interop code should look like this:
[DllImportAttribute("kernel32.dll", EntryPoint="GetProcessId")]
public static extern uint GetProcessId([In] System.IntPtr process);
Case matters sometimes, and in particular, it matters in the Windows APIs. Are you refering to the API function GetProcessId here (lower-case last letter d)?

Categories