Click here to Skip to main content
Sign Up to vote bad
good
See more: C++Win32
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.
 
//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 26 Apr '11 - 11:25
Edited 26 Apr '11 - 11:53

Comments
SAKryukov - 26 Apr '11 - 17:56
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:11
good fix

4 solutions

Here's an example.
 
C++ code
-----------
 
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
---------------------
 
[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);
}
  Permalink  
Comments
SAKryukov - 26 Apr '11 - 18:01
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:55
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:54
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.
SAKryukov - 26 Apr '11 - 19:33
Answered in the [EDIT] section of the updated Solution. --SA
Olivier Levrey - 28 Apr '11 - 9:06
Good. A 5. By the way, OP sent you a comment but posted it as an answer instead...
Nishant Sivakumar - 28 Apr '11 - 9:08
Thanks Olivier.
Member 4581741 - 28 Apr '11 - 9:21
Thanks Nishant. Perfect. Now i got an array from my calling application to C++. 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.
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:
//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:
        //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);
        }
  Permalink  
Comments
Member 4581741 - 28 Apr '11 - 13:36
Perfect .. This worked fine .. Thanks
Olivier Levrey - 29 Apr '11 - 3:41
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
  Permalink  
Comments
Albert Holguin - 26 Apr '11 - 19:16
OP answered your question with a comment in nishant's solution...
SAKryukov - 26 Apr '11 - 19:27
Thank you. --SA
SAKryukov - 26 Apr '11 - 19:33
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.
  Permalink  
Comments
Olivier Levrey - 28 Apr '11 - 9:05
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
Your Filters
Interested
Ignored
     
0 Sergey Alexandrovich Kryukov 414
1 Arun Vasu 253
2 OriginalGriff 210
3 CPallini 163
4 Aarti Meswania 158
0 Sergey Alexandrovich Kryukov 10,129
1 OriginalGriff 7,749
2 CPallini 4,181
3 Rohan Leuva 3,482
4 Maciej Los 2,999


Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 28 Apr 2011
Copyright © CodeProject, 1999-2013
All Rights Reserved. Terms of Use
Layout: fixed | fluid