用于使用 C++ 的类型编组类型

发布于 2024-10-11 03:52:47 字数 359 浏览 1 评论 0原文

我想通过 C# 调用一个 C++ 函数(在 win32 .dll 中)。 C++ 函数是这样的:

bool pack(BYTE * messageFields[]);

该函数想要在输入参数的某些索引处填充一些数据(例如字符串或字节[])。 所以请告诉我 C#.NET 中的封送处理应该如何?我尝试了多种类型,但出现错误或对我的参数没有影响!

C# 代码必须打开本机 .DLL :

[DllImport("c:\\theDllName.dll")]
        public static extern bool pack( // what is here? )

i wanna call a c++ function (in win32 .dll) by C#.
the c++ function in like this:

bool pack(BYTE * messageFields[]);

the function wants to fill some data (eg. a string or byte[]) at some indexes of the input argument.
so plz tell me how the marshaling should be in C#.NET? i tried many types but got errors or no effects to my parameter!

the C# code must open native .DLL :

[DllImport("c:\\theDllName.dll")]
        public static extern bool pack( // what is here? )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

八巷 2024-10-18 03:52:47

System.Byte[] 可能是您正在寻找的。

抱歉,没有看到您有 BYTE* ...[]。

一些代码

extern "C" UNMANAGEDCPP_API int fnUnmanagedCpp(BYTE* test[], int nRows, int nCols)
{
    //do stuff
    std::cout << "called!" << std::endl;

    for ( int i = 0; i < nRows; ++i )
    {
        for ( int j = 0; j < nCols; ++j )
        {
            std::cout << int ( test[i][j] ) << std::endl;
        }
    }

    test[0][0] = 23;

    return 0;
}

在 C# 中:

   [DllImport("UnmanagedCpp.dll", CallingConvention=CallingConvention.Cdecl)]
   public static extern int fnUnmanagedCpp(IntPtr[] buffer, int nRows, int nCols );

   public static IntPtr[] Marshall2DArray(byte[][] inArray)
   {
       IntPtr[] rows = new IntPtr[inArray.Length];

       for ( int i = 0; i < inArray.Length; ++i )
       {
           rows[i] = Marshal.AllocHGlobal(inArray[i].Length * Marshal.SizeOf(typeof(byte)));
           Marshal.Copy( inArray[i], 0, rows[i], inArray[i].Length );
       }

       return rows;
   }

   public static void Copy2DArray( IntPtr[] inArray, byte[][] outArray )
   {
       Debug.Assert(inArray.Length == outArray.Length);

       int nRows = Math.Min( inArray.Length, outArray.Length );

       for (int i = 0; i < nRows; ++i)
       {
           Marshal.Copy(inArray[i], outArray[i], 0, outArray[i].Length);
       }
   }

   public static void Free2DArray(IntPtr[] inArray)
   {
       for (int i = 0; i < inArray.Length; ++i)
       {
           Marshal.FreeHGlobal(inArray[i]);
       }
   }

    static void Main(string[] args)
    {
        byte[][] bTest = new byte[2][] { new byte[2] { 1, 2 }, new byte[2] { 3, 4 } };

        IntPtr[] inArray = Marshall2DArray(bTest);

        fnUnmanagedCpp(inArray, 2, 2);

        Copy2DArray(inArray, bTest);
        Free2DArray(inArray);

        System.Console.WriteLine(bTest[0][0]);
    }

我希望这会有所帮助,也许还有另一种更好/更简单的方法来做到这一点。请注意,该代码仅用于“说明”,可能包含错误。

基本上,传入一组 IntPtr 并手动编组......

System.Byte[] is what you are probably looking for.

Sorry didn'see you had BYTE* ...[].

Some code

extern "C" UNMANAGEDCPP_API int fnUnmanagedCpp(BYTE* test[], int nRows, int nCols)
{
    //do stuff
    std::cout << "called!" << std::endl;

    for ( int i = 0; i < nRows; ++i )
    {
        for ( int j = 0; j < nCols; ++j )
        {
            std::cout << int ( test[i][j] ) << std::endl;
        }
    }

    test[0][0] = 23;

    return 0;
}

And in C#:

   [DllImport("UnmanagedCpp.dll", CallingConvention=CallingConvention.Cdecl)]
   public static extern int fnUnmanagedCpp(IntPtr[] buffer, int nRows, int nCols );

   public static IntPtr[] Marshall2DArray(byte[][] inArray)
   {
       IntPtr[] rows = new IntPtr[inArray.Length];

       for ( int i = 0; i < inArray.Length; ++i )
       {
           rows[i] = Marshal.AllocHGlobal(inArray[i].Length * Marshal.SizeOf(typeof(byte)));
           Marshal.Copy( inArray[i], 0, rows[i], inArray[i].Length );
       }

       return rows;
   }

   public static void Copy2DArray( IntPtr[] inArray, byte[][] outArray )
   {
       Debug.Assert(inArray.Length == outArray.Length);

       int nRows = Math.Min( inArray.Length, outArray.Length );

       for (int i = 0; i < nRows; ++i)
       {
           Marshal.Copy(inArray[i], outArray[i], 0, outArray[i].Length);
       }
   }

   public static void Free2DArray(IntPtr[] inArray)
   {
       for (int i = 0; i < inArray.Length; ++i)
       {
           Marshal.FreeHGlobal(inArray[i]);
       }
   }

    static void Main(string[] args)
    {
        byte[][] bTest = new byte[2][] { new byte[2] { 1, 2 }, new byte[2] { 3, 4 } };

        IntPtr[] inArray = Marshall2DArray(bTest);

        fnUnmanagedCpp(inArray, 2, 2);

        Copy2DArray(inArray, bTest);
        Free2DArray(inArray);

        System.Console.WriteLine(bTest[0][0]);
    }

I hope this helps, maybe there is another better/simpler way to do this. Please note that the code is only for "illustration" and might contain bugs.

Basically one passes in an array of IntPtrs and manually marshals...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文