Click here to Skip to main content
15,867,594 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I am creating a Win32 Dll Wrapper around my C# class library.
I am able to pass string from my C# to C++ application.
But i am not sure as to how can i pass string array in Win32 C++ project.

MIDL
//C# code
void Test(string lFile, int ver);
//C++ Code
extern "C" __declspec(dllexport)
void _stdcall Test(char *lFile, int ver)
{
    //Initialize COM.
    psShrinkGrowD->Shrink(_bstr_t(largeFile), version);
    // Uninitialize COM.
}



I am able to pass string which is (char array in C++) and able to receive string.
But if i want to pass string array suppose
void Test(string[] versions) then is there any way to do it in Win32 C++ Project.
Help would be really appreciated.
Posted
Updated 26-Apr-11 11:53am
v3
Comments
Sergey Alexandrovich Kryukov 26-Apr-11 17:56pm    
Not only you messed up -> formatting, but the title of your Question was ***very misleading***. It's important to attract right expert to your question; my first reaction was "gibberish, I don't want to read it", even though your question makes perfect sense.

Fixed. Please, next time be accurate, to your own benefit.
--SA
Albert Holguin 26-Apr-11 18:11pm    
good fix

Here's an example.

C++ code
-----------

C++
extern "C" __declspec(dllexport) void _stdcall Test(char **files, int count)
{
    for(int i=0; i<count; i++)
    {
        char* s = *(files + i);
        // do more stuff...
    }
}


C# calling code
---------------------

C#
[DllImport("YourLibrary.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void Test(string[] files, int count);

static void Main()
{
    string[] strings = new[] { "aaa", "bbb" };
    Test(strings, strings.Length);
}
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 26-Apr-11 18:01pm    
Looks correct, my 5.
As I did not really understand what should use what, I added an note on using C++/CLI and/or mixed-mode project.
Please see.
--SA
Member 4581741 27-Apr-11 8:55am    
Actually my question was not completely clear. My bad for that.
Actually the Win32 C++ is just the entry point for the calling application where it will call a function from C# class library and pass the same parameters.
Your code works perfect.

But what i want is that in my Win32 app Test function i am taking the parameters (Test(char **files, int count) passed from calling function Test(string[] files, int count). Just like your solution.

Now i don't want to use the values in the C++ application, but C++ app Test function will call a function from C# class library where i want to use the string array.

Ex: string
void _stdcall Test(char *lFile, int ver)
{
//Initialize COM.
psShrinkGrowD->Test(_bstr_t(largeFile), version);
// Uninitialize COM.
}
Here i am passing string from my calling application to C++ (char *lFile) which in turn calls Test function from C# class library where it is again being read as string.

Thanks
Member 4581741 26-Apr-11 18:54pm    
Ok good.
Will give a try tomorrow.

Thank you so much.
Actually i am creating a Win32 wrapper DLL around C# class library because my dll will be used by vb.net and also Delphi.

Also is it possible to create multidimentional array in Win32 C++ ?

Thanks. Appreciated.
Sergey Alexandrovich Kryukov 26-Apr-11 19:33pm    
Answered in the [EDIT] section of the updated Solution.
--SA
Olivier Levrey 28-Apr-11 9:06am    
Good. A 5.
By the way, OP sent you a comment but posted it as an answer instead...
Now from this C++ function if i want to pass the array or array values (received) to C# class library, is there a way to do that.

First you need to give a callback to your C++ code, then you need to convert the unmanaged data to managed data. You can do something like that:

C++ code:
C++
//the type of the callback
typedef void (__stdcall *YOUR_CALLBACK)(char** files, int count);
//the function to set the callback
extern "C" __declspec(dllexport) void __stdcall SetCallback(YOUR_CALLBACK callback)
{
    //just to try the callback:
    //fill a string array
    char* files[] = { "first string", "second string" };
    //and pass it to the callback
    callback(files, 2);
}


C# code:
C#
//declare the callback delegate
delegate void YOUR_CALLBACK(IntPtr files, int count);
//import the callback setter
[DllImport("Native.dll", CallingConvention = CallingConvention.StdCall)]
static extern void SetCallback(YOUR_CALLBACK callback);
//the callback
static void CalledFromC(IntPtr files, int count)
{
    //convert the received pointer into a pointer array
    IntPtr[] stringPointers = new IntPtr[count];
    Marshal.Copy(files, stringPointers, 0, count);
    //convert the pointer array into a string array
    string[] strings = new string[count];
    for (int i = 0; i < count; i++)
        strings[i] = Marshal.PtrToStringAnsi(stringPointers[i]);
    //now you have your strings
    ...
}

[STAThread]
static void Main()
{
    //you must give the callback to your C++ dll somewhere in your code
    SetCallback(CalledFromC);
}
 
Share this answer
 
Comments
Member 4581741 28-Apr-11 13:36pm    
Perfect .. This worked fine ..
Thanks
Olivier Levrey 29-Apr-11 3:41am    
You are welcome.
Do you want to use C# library in native C++ or native C++ library in C# project?
First thing is much more difficult. (And do yourself a favor, do not use COM!)
If you need to use .NET assembly in C++, consider using C++/CLI or mixed-mode (managed+unmanaged) project combining C++ and C++/CLI.

[EDIT]

In reply to a follow-up question:
In C++ you can use regular multi-dimensional arrays of any rank like [a, b, c, d], you can create a jagged arrays (arrays of arrays, in this way, each inner array can be of different length) and you can use containers with array functionality such as std::vector; for jagged multi-dimensional array you can use vector of vector. Of course you can do all that with C# and Delphi. Additionally, you can implement custom container classes with array functionality using operator overloading: you can define indexing operator "[]".

—SA
 
Share this answer
 
v2
Comments
Albert Holguin 26-Apr-11 19:16pm    
OP answered your question with a comment in nishant's solution...
Sergey Alexandrovich Kryukov 26-Apr-11 19:27pm    
Thank you.
--SA
Sergey Alexandrovich Kryukov 26-Apr-11 19:33pm    
Answered in the [EDIT] section of the updated Solution.
--SA
Thanks Nishant.
Perfect.

Now from this C++ function if i want to pass the array or array values (received from calling app) to C# class library, is there a way to do that.

Please let me know.

Thanks.
 
Share this answer
 
v2
Comments
Olivier Levrey 28-Apr-11 9:05am    
If you want to give feedback to Nishant, then don't post a solution. Post a comment under his solution instead. Otherwise he will not be notified by email.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900