2015-08-26 2 views
1

Я инженер по автомобильным вопросам, и моя компания решила купить аппаратное обеспечение, для которого API был только на C++ (я получил неидентифицированные DLL и файлы заголовков). Проблема в том, что я только закодирован на C#, и большинство наших приложений очень легко создавать, поскольку поставщик оборудования всегда дает нам API в C# (управляемая dll). Теперь мне нужно преобразовать все функции в неизменной dll в функции C#. Это происходит гладко, пока я не наткнулся наПортирование структуры C++ на C# (из неуправляемой dll)

typedef struct can_msg 
{ 
    unsigned short ide;       // Standard/extended msg 
    unsigned int id;       // 11 or 29 bit msg id 
    unsigned short dlc;       // Size of data 
    unsigned char data[CAN_MSG_DATA_LEN];  // Message pay load 
    unsigned short rtr;       // RTR message 
} can_msg_t; 

Я понятия не имею, как использовать его, как эта структура не является аргументом для функции, например:

VTC1010_CAN_BUS_API int CAN_Transmission(can_msg_t *msg); 

Пожалуйста, помогите ребята. Не начинай избивать меня из-за моей нехватки знаний. Я пытался найти, но все это слишком сложно для меня.

+1

Вы уже знайте, как выглядят короткие и int. Char [] требует 'фиксированных байтовых данных [что-то]'. –

ответ

0

Это быстрое и грязное преобразование через сито P/Invoke Interop Assistant.

Введите код:

#define CAN_MSG_DATA_LEN 100 // adjust correct value here 

typedef struct can_msg 
{ 
    unsigned short ide;       // Standard/extended msg 
    unsigned int id;       // 11 or 29 bit msg id 
    unsigned short dlc;       // Size of data 
    unsigned char data[CAN_MSG_DATA_LEN];  // Message pay load 
    unsigned short rtr;       // RTR message 
} can_msg_t; 

int CAN_Transmission(can_msg_t *msg); 

Выходной код:

public partial class NativeConstants { 

    /// CAN_MSG_DATA_LEN -> 100 
    public const int CAN_MSG_DATA_LEN = 100; 
} 

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi)] 
public struct can_msg { 

    /// unsigned short 
    public ushort ide; 

    /// unsigned int 
    public uint id; 

    /// unsigned short 
    public ushort dlc; 

    /// unsigned char[100] 
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=100)] 
    public string data; 

    /// unsigned short 
    public ushort rtr; 
} 

public partial class NativeMethods { 

    /// Return Type: int 
    ///msg: can_msg_t* 
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="CAN_Transmission")] 
public static extern int CAN_Transmission(ref can_msg msg) ; 

} 
+0

Спасибо за ваш ответ. Это дает мне отправную точку. Высоко оценил –

+0

Спасибо! Извините, но я не вижу ссылки на ваш комментарий, вы что-то забыли? – Aybe

+0

Я редактировал его. –

1

Предполагая, что у вас нет знаний о том, как использовать несанкционированные DLL-файлы в управляемых приложениях .net Я могу рассказать вам некоторые очень простые вещи. Путь к созданию «обертки» для неуправляемых классов с использованием Visual C++, тогда вы можете использовать классы, определенные в этой оболочке, для работы с вашим неуправляемым кодом.

Вы можете найти хороший учебник здесь: http://www.codeproject.com/Articles/14180/Using-Unmanaged-C-Libraries-DLLs-in-NET-Applicatio

Извините за не более конкретным, но вы должны начать изучать, прежде чем создавать код. Удачи!

0
static class NativeMethods 
{ 


    // To load dll 
    [DllImport("kernel32.dll")] 
    public static extern IntPtr LoadLibrary(string dllToLoad); 
    // To get the Address of the Function 
    [DllImport("kernel32.dll")] 
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); 
    // Freeing up the Library for other usage. 
    [DllImport("kernel32.dll")] 
    public static extern bool FreeLibrary(IntPtr hModule); 
} 
class manageCAN 
{ 
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
    // Declaration of function to get 
    private delegate int CAN_Initial(int baudRate); 
    private delegate int Library_Release(); 

    // Getting the String for .dll Address 
    static readonly string dllfile = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\VTC1010_CAN_Bus.dll"; 

    public int IntialiseCAN (int baudrate) 
    { 
     // Loading dll using Native Methods 
     IntPtr pDll = NativeMethods.LoadLibrary(dllfile); 
     if (pDll== IntPtr.Zero) 
     { 
      MessageBox.Show("Loading Failed"); 
     } 
     // Getting the Adress method 
     IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "CAN_Initial"); 
     CAN_Initial initialiseCAN = (CAN_Initial)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(CAN_Initial)); 
     int result = initialiseCAN(baudrate); 
     bool iresult = NativeMethods.FreeLibrary(pDll); 
     return result; 
    } 
} 

Это работает, но я запутался, когда я получил структуру в качестве аргумента, поэтому я спросил этот вопрос

Смежные вопросы