Calling native C++ function using DefinePInvokeMethod and returning a calculated value as a pointer/

M

Marek

Hi
I need to call a native function in a C++ dll from my C#. The C++ function
declaration is shown below.

The C# code that I have been trying to perform the call is also shown below.
All it is trying to do is to pass in two integers, add them together and
return the result in the third parameter (byref/as a pointer).

The problem is how do I specify the third parameter to be a pointer to type
int?

Thanks for any help in advance.

Marek

C++ function declaration
================================================================================
extern "C"
{
__declspec( dllexport ) void WINAPI SumIntWithRef(int a, int b, int* pc)
{
*pc = a + b;
}
}

C# call
============================================================================================

string dllName = @"NativeFunctionDLL.dll";
string entryPointName = "SumIntWithRef";

//...Set up the return value:
Type returnType = null;

//...Set up the parameters:
Type[] parameterTypes = new Type[3];
object[] parameterValues = new object[3];

parameterTypes[0] = typeof(int);
parameterValues[0] = 2;

parameterTypes[1] = typeof(int);
parameterValues[1] = 3;

parameterTypes[2] = typeof(int); //...How should this one be
specified?
parameterValues[2] = 0;

// Create a dynamic assembly and a dynamic module
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tempDll";
AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =
assemblyBuilder.DefineDynamicModule("tempModule");

// Dynamically construct a global PInvoke signature
// using the input information
MethodBuilder methodBuilder =
moduleBuilder.DefinePInvokeMethod(entryPointName,
dllName,
MethodAttributes.Static
| MethodAttributes.Public | MethodAttributes.PinvokeImpl,
CallingConventions.Standard,
returnType,
parameterTypes,
CallingConvention.Winapi,
CharSet.Ansi);

//...This global method is now complete:
methodBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig);
moduleBuilder.CreateGlobalFunctions();

// Get a MethodInfo for the PInvoke method
MethodInfo methodInfo = moduleBuilder.GetMethod(entryPointName);

// Invoke the static method and return whatever it returns
ParameterInfo[] parameterInfo = methodInfo.GetParameters();

Object returnValue = new Object();

try
{
methodInfo.Invoke(null, parameterValues);
MessageBox.Show(String.Format("Value calculated: {0}",
parameterValues[2]));
 
W

Willy Denoyette [MVP]

| Hi
| I need to call a native function in a C++ dll from my C#. The C++
function
| declaration is shown below.
|
| The C# code that I have been trying to perform the call is also shown
below.
| All it is trying to do is to pass in two integers, add them together and
| return the result in the third parameter (byref/as a pointer).
|
| The problem is how do I specify the third parameter to be a pointer to
type
| int?
|
| Thanks for any help in advance.
|
| Marek
|
| C++ function declaration
|
================================================================================
| extern "C"
| {
| __declspec( dllexport ) void WINAPI SumIntWithRef(int a, int b, int* pc)
| {
| *pc = a + b;
| }
| }
|
| C# call
|
============================================================================================
|
| string dllName = @"NativeFunctionDLL.dll";
| string entryPointName = "SumIntWithRef";
|
| //...Set up the return value:
| Type returnType = null;
|
| //...Set up the parameters:
| Type[] parameterTypes = new Type[3];
| object[] parameterValues = new object[3];
|
| parameterTypes[0] = typeof(int);
| parameterValues[0] = 2;
|
| parameterTypes[1] = typeof(int);
| parameterValues[1] = 3;
|
| parameterTypes[2] = typeof(int); //...How should this one be
| specified?
| parameterValues[2] = 0;
|
| // Create a dynamic assembly and a dynamic module
| AssemblyName assemblyName = new AssemblyName();
| assemblyName.Name = "tempDll";
| AssemblyBuilder assemblyBuilder =
| AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
| AssemblyBuilderAccess.Run);
| ModuleBuilder moduleBuilder =
| assemblyBuilder.DefineDynamicModule("tempModule");
|
| // Dynamically construct a global PInvoke signature
| // using the input information
| MethodBuilder methodBuilder =
| moduleBuilder.DefinePInvokeMethod(entryPointName,
|
dllName,
|
MethodAttributes.Static
|| MethodAttributes.Public | MethodAttributes.PinvokeImpl,
|
CallingConventions.Standard,
|
returnType,
|
parameterTypes,
|
CallingConvention.Winapi,
|
CharSet.Ansi);
|
| //...This global method is now complete:
|
methodBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig);
| moduleBuilder.CreateGlobalFunctions();
|
| // Get a MethodInfo for the PInvoke method
| MethodInfo methodInfo =
moduleBuilder.GetMethod(entryPointName);
|
| // Invoke the static method and return whatever it returns
| ParameterInfo[] parameterInfo = methodInfo.GetParameters();
|
| Object returnValue = new Object();
|
| try
| {
| methodInfo.Invoke(null, parameterValues);
| MessageBox.Show(String.Format("Value calculated: {0}",
| parameterValues[2]));
|
|



Use the DefinePInvokeMethod overload that takes a
parameterTypeRequiredCustomModifiers and set IsByRef for the third argument.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top