Discussion:
Dynamic P/Invoke Problem
(too old to reply)
Fábio Chicout
2010-01-20 00:21:01 UTC
Permalink
Hi, I'm on a project that needs interop with native dlls. On some point, I
need to interop with a function like this:



extern "C" _declspec(dllexport) unsigned int TestByteArrayUp(unsigned char*
bArray, int len){
unsigned char arr[] = {80, 25, 14, 42, 74, 56};
memcpy(bArray, arr, len);
std::cout << "[unmanaged]\n" << std::endl;
for (int i=0; i<len; i++)
std::cout << i << " = " << bArray[i] << std::endl;
return 21;
}



And on C# I need to use P/Invoke on a "dynamic way", with the pair
LoadLibrary and GetProcAddress, so I can point to a dll that's not know
before runtime.

My C# Test code is the one below:



When I run this code, I got an System.ExecutionEngineException was unhandled
Message="Exception of type 'System.ExecutionEngineException' was thrown."
InnerException:

Googling around, I've found that this should be a problem on Marshalling,
but I'm unable to see where I'm wrong.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace PinvokeTest
{
class Program
{
static void Main(string[] args)
{
IntPtr library =
LoadLibrary(@"C:\Users\fcfm\Documents\Visual Studio
2008\Projects\PinvokeTest\Debug\TestDLL.dll");
IntPtr funcAddr = GetProcAddress(library,
"TestByteArrayUp");
TestByteArrayUp func =
(TestByteArrayUp)Marshal.GetDelegateForFunctionPointer(funcAddr,
typeof(TestByteArrayUp));
byte[] arr = new byte[6];
uint ret = func(out arr, arr.Length);
Console.WriteLine("[Modified Managed ByteArray]:");
foreach (byte i in arr)
{
Console.WriteLine(i);
}
Console.WriteLine("Unmanaged return code on managed
code: {0}", ret);
Console.ReadKey();
}
internal delegate uint
TestByteArrayUp([MarshalAs(UnmanagedType.LPArray)] out byte[] bArray, int
len);

[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(String libName);

[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr libPtr,
String funcName);
}
}
Christian Fröschlin
2010-01-20 08:45:55 UTC
Permalink
Post by Fábio Chicout
Googling around, I've found that this should be a problem on Marshalling,
but I'm unable to see where I'm wrong.
Are you sure that bArray should be an "out" Parameter?
It looks like your passing an array in to be modified.
Fábio Chicout
2010-01-20 17:59:02 UTC
Permalink
Yes, I'm sure I need to pass an byte array reference as a parameter to be
filled by the native code.
Post by Christian Fröschlin
Post by Fábio Chicout
Googling around, I've found that this should be a problem on Marshalling,
but I'm unable to see where I'm wrong.
Are you sure that bArray should be an "out" Parameter?
It looks like your passing an array in to be modified.
.
Fábio Chicout
2010-01-20 18:31:01 UTC
Permalink
Thanks for the answer, Christian!

Taking the out parameter was the solution! I wasn't aware that the
UnmanagedType.LPArray was exactly what I want. Sorry, my distraction.

Thanks again!
Post by Fábio Chicout
Yes, I'm sure I need to pass an byte array reference as a parameter to be
filled by the native code.
Post by Christian Fröschlin
Post by Fábio Chicout
Googling around, I've found that this should be a problem on Marshalling,
but I'm unable to see where I'm wrong.
Are you sure that bArray should be an "out" Parameter?
It looks like your passing an array in to be modified.
.
Loading...