互操作:C#和本机Win32 C ++代码;字符串数组 [英] Interoperation: C# and native Win32 C++ code; arrays of strings

查看:66
本文介绍了互操作:C#和本机Win32 C ++代码;字符串数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在围绕我的C#类库创建Win32 Dll包装器.
我可以将字符串从C#传递到C ++应用程序.
但是我不确定如何在Win32 C ++项目中传递字符串数组.

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.
}




我可以传递字符串(在C ++中为char数组),并且可以接收字符串.
但是如果我想传递字符串数组,请假设
无效的测试(字符串[]版本),那么在Win32 C ++项目中有什么方法可以实现.
我们将不胜感激.




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.

推荐答案

这里是一个例子.

C ++代码
-----------

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#调用代码
---------------------



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);
}


现在,如果我想将数组或数组值(接收到的)传递给C#类库,可以使用此C ++函数中的方法.

首先,您需要为C ++代码提供回调,然后需要将非托管数据转换为托管数据.您可以执行以下操作:

C ++代码:
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#代码:



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);
}


您要在本机C ++中使用C#库还是在C#项目中使用本机C ++库?
第一件事要困难得多. (并且帮自己一个忙,不要使用COM !)
如果需要在C ++中使用.NET程序集,请考虑使用C ++/CLI或结合了C ++和C ++/CLI的混合模式(托管+非托管)项目.



回答后续问题:
在C ++中,您可以使用任意级别的常规多维数组,例如[a, b, c, d],可以创建锯齿状的数组(数组的数组,这样每个内部数组可以具有不同的长度),并且可以使用具有数组功能的容器如std::vector;对于锯齿状的多维数组,您可以使用向量vector.当然,您可以使用C#和Delphi来完成所有这些工作.此外,您可以使用运算符重载来实现具有数组功能的自定义容器类:您可以定义索引运算符"[]".
—SA
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.



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


这篇关于互操作:C#和本机Win32 C ++代码;字符串数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆