Passing array as a parameter from C# to C++ dll

G

Guest

I'm using VS2005 to write a C++ dll to use some Win32 APIs, and I'm calling
the dll from a C# program. I've created the following C# class that I'm using
to create an array to pass to the dll. The C# program creates the array with
more than one dimension, but the C++ dll only sees the first dimension. Here
is the class that I used to create the array (it will eventually contain much
more than a string):

namespace TestObjectClass
{
public class TestObject
{
public TestObject(string Name)
{
name = Name;
}
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
}

This is the C# caller:

....
using System.Runtime.InteropServices;
using TestObjectClass;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
TestObject[] testObjectArray = new TestObject[4];
testObjectArray[0] = new TestObject("Name0");
testObjectArray[1] = new TestObject("Name1");
testObjectArray[2] = new TestObject("Name2");
testObjectArray[3] = new TestObject("Name3");

// call C++ dll here
processTestObjectArrayClass.ProcessArray(this.Handle,
testObjectArray);

}
}
public class processTestObjectArrayClass
{
[DllImport(@"..\..\..\Debug\TestArrayDll.dll")]
public static extern int ProcessArray(IntPtr handle, TestObject[]
testObjectArray);
}
}

And here is the C++ dll:
....
#using <TestObjectClass.dll>
....
using namespace TestObjectClass;
....
int __clrcall ProcessArray(HWND hWnd, array<TestObject^>^ testObjectArray)
{
for (int i = 0; i < testObjectArray->Length; i++)
{
pin_ptr<const wchar_t> name =
PtrToStringChars(testObjectArray->Name->ToString());
::MessageBox(hWnd, name, L"Test Object Array", MB_OK);
}
return 0;
}

I created the dll to use shared MFC.

What am I doing to cause only the first dimension in the array to be seen?

Thanks,
David
 
G

Gary Chang[MSFT]

Hi David,

Thank you posting!

Would you please provide more detailed information about this issue?

1. How about your C++ DLL, Is it a MFC DLL?

2. How do you export the ProcessArray(...) function in that DLL, since you
Pinvoke it in the C# application, why do you specify it as a __clrcall
function?

3. Based on your code snippet, you only create 1 dimension's TestObject
array. If you create a 2 dimensions' array as [4,4], what's that array
length you get in the C++ dll's ProcessArray(...) function?

Thanks!

Best regards,

Gary Chang
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Gary,

1. Yes, it is an MFC dll.

2. The __clrcall was an attempt on my part to resolve a compilation error,
but I've removed that. The result is the same.

3. Yes, you are correct; the array is only one dimension. I should have used
the term "element," I believe. I create a one-dimension array in C# with 4
elements, and I get a one-dimension array with only 1 element in the C++ dll.

Thanks...David
 
G

Gary Chang[MSFT]

Hi David,
2. The __clrcall was an attempt on my part to resolve a
compilation error, but I've removed that. The result is the same.

OK, I got it. If so how do you export that function?

Would you please send us the corresponding self-alone repro
projects(zipped) for repro, we need perform some research on them? (please
remove the "online" of my email address alias)

Thanks for your understanding.

Best regards,

Gary Chang
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Here is the export for the C++ dll (the .def file):

; TestArrayDll.def : Declares the module parameters for the DLL.

LIBRARY "TestArrayDll"

EXPORTS
; Explicit exports can go here

ProcessArray




"Gary Chang[MSFT]" said:
Hi David,
2. The __clrcall was an attempt on my part to resolve a
compilation error, but I've removed that. The result is the same.

OK, I got it. If so how do you export that function?

Would you please send us the corresponding self-alone repro
projects(zipped) for repro, we need perform some research on them? (please
remove the "online" of my email address alias)

Thanks for your understanding.

Best regards,

Gary Chang
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Gary Chang[MSFT]

Hi David,

Based on my experience, if you PInvoke a Win32 DLL function, the target
function should be an unmanaged one. However your exported DLL function is
not a pure native function, it has a parameter of a managed type.

In the general convension, the Pinvoke scenario will marshal and pass its
managed array object to a DLL function's unmanaged heap(via defining the
array's length).

Considered your DLL is already an assembly, I suggest you can reference
that assembly directly in your winform application, and use that function
as a managed one directly.

Thanks!

Best regards,

Gary Chang
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

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