2015-03-20 14 views
5

Tôi có phương thức thư viện C++ mà tôi muốn gọi từ tập lệnh Unity C#.Chuyển mảng byte từ Unity C# sang phương thức thư viện C++

Tôi hiểu rằng có ba bước chính. Đầu tiên, để khai báo các phương thức C++ là extern "C". Thứ hai, sử dụng trước khi khai báo phương thức extern C# tương ứng. Thứ ba, đặt tên cho tệp thư viện bằng tiền tố lib (ví dụ: libfoobar.so) và đặt nó vào thư mục plugin Unity.

Cho đến nay rất tốt - nếu tôi chỉ chuyển các loại thông số đơn giản như int từ C# vào C++. Tuy nhiên, để vượt qua một tham số byte[], tôi sẽ cần tính đến các cách khác nhau C# và C++ xử lý bộ nhớ và con trỏ. Tôi đã không thể tìm thấy một ví dụ dứt khoát về cách này nên được thực hiện.

Câu hỏi của tôi: cách chuyển một số byte[] từ tập lệnh Unity C# vào một phương thức thư viện C++ bên ngoài?

+0

Đây có phải là P/phương thức Invoke? Bạn cũng có thể sử dụng C++ CLI. Tôi đã nghe nói rằng C + + CLI cho phép bạn kiểm soát nhiều hơn. Nhưng, tôi chưa bao giờ làm điều đó. Mang nó theo một hạt muối. –

+1

Đừng quên 'CallingConvention = CallingConvention.Cdecl' từ DllImport của bạn vì bạn đang sử dụng' extern "C" ' – cubrr

+0

@Golazo - không sử dụng P/Invoke, chỉ cần khai báo C++ extern là' extern "C" 'và tham chiếu nó từ C# thông qua thuộc tính 'DllImport'. Không cần lệnh P/Invoke, ít nhất là không truyền các kiểu tham số đơn giản. – Ghopper21

Trả lời

2

Bạn phải thay đổi định nghĩa phương thức của mình để thực hiện IntPtr. Đây là cách C# để xác định con trỏ tới bộ nhớ không được quản lý. Để tạo con trỏ này, hãy sử dụng Marshal.AllocHGlobal() và sau đó sao chép dữ liệu vào đó bằng cách sử dụng Marshal.Copy().

Ví dụ (không kiểm tra):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace Assets.Scripts 
{ 
    public class DLLCall 
    { 

     [DllImport("thedll")] 
     public static extern void TheCall(IntPtr byteArray, int size); 

     public void PerformCall(byte[] data) 
     { 
      IntPtr unmanagedArray = Marshal.AllocHGlobal(data.Length); 
      Marshal.Copy(data, 0, unmanagedArray, data.Length); 

      TheCall(unmanagedArray, data.Length); 

      Marshal.FreeHGlobal(unmanagedArray); 
     } 

    } 
} 

Chú ý rằng bạn có để giải phóng bộ nhớ không được quản lý bằng tay bằng cách sử dụng Marshal.FreeHGlobal. Sau đó, bộ nhớ không còn hợp lệ để thư viện C++ không thể sử dụng nữa. Nếu nó cần truy cập vào mảng tại điểm sau, hãy xóa cuộc gọi FreeHGlobal và đảm bảo xóa bộ nhớ sau khi thư viện không còn yêu cầu quyền truy cập vào bộ nhớ đó nữa.

3

công trình cho tôi:

trong sự hiệp nhất:

[DllImport ("dllplugin")] 
public static extern void Method (byte[] bytes); 

trong C++ Plugin

#define EXPORT_API __declspec(dllexport) 

extern "C" void EXPORT_API Method(unsigned char* bytes) 
+0

Tôi đang đi qua các mảng byte từ sự thống nhất để c + + plugin như thế này, Nó hoạt động tốt nhưng untiy gửi 17 byte otherside (C + +) nhận được 4 byte only.what là lý do gì? – Rajesh

Các vấn đề liên quan