2016-01-15 6 views
0

У меня есть интерфейс связи с машиной и получена DLL, снабженная множеством функций для использования. все работает отлично, пока у меня есть общение. если нет связи, скажем, 5 минут, функции больше не работают. я думаю, это потому, что все это очищается сборщиком мусора. после некоторых исследований я, вероятно, следует прикрепить его с GCHandle.Alloc(object, GCHandleType.Pinned);связать объект с не примитивными данными в C#

вот часть кода:

Объектом

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public class DNCC_PARAM 
{ 
    public int nMacNo; 
    public int nOwnPort; 
    public int nIpAddr; 
    public int nNCPort; 

    [MarshalAsAttribute(UnmanagedType.FunctionPtr)] 
    public Delegate CallBackFunction; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] 
    public short[] arrTimeout = new short[20]; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] 
    public short[] arrRetry = new short[20]; 
} 

часть импорта DLL

[DllImport(@"path to dll", CharSet = CharSet.Ansi)] 
public static extern int Initialize([In()] DNCC_PARAM dncPara); 

[DllImport(@"path to dll", CharSet = CharSet.Ansi)] 
private static extern int dncc_Connect(int hdl); 

[DllImport(@"path to dll", CharSet = CharSet.Ansi)] 
private static extern int dncc_Disconnect(int hdl); 

экземпляр объекта

DNCC_PARAM param = new DNCC_PARAM(); 

инициализации СООБЩЕНИЮ

// fill the object with some data 
param.nMacNo = 1; 
param.nOwnPort = 7005; 
param.nIpAddr = (int)IPAddress.Parse("192.168.0.10").Address; 
param.nNCPort = 7005; 
param.CallBackFunction = new TypeOfCallBackFunction(AppCallBack); 

// init the communication 
nDNCC_HANDLE = Initialize(param); 

функция обратного вызова

private void AppCallBack(int iHandle, int iEvent, IntPtr arg) 
{ 
    // doing some stuff here 
} 

поэтому, когда я пытаюсь прикрепить объект, как, что GCHandle.Alloc(param, GCHandleType.Pinned); я получаю сообщение о том, что объект не содержит примитивные данных. как я могу предотвратить очистку объекта GC?

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

ответ

0

Я думаю, что вы ищете Marshal.StructureToPtr. Суть здесь в том, что выделенный вами объект управления не имеет макета памяти, который соответствует неуправляемому макету, который вы пытаетесь описать с помощью атрибутов MarshalAs. Итак, вам нужен класс Marshal, чтобы создать неуправляемую копию структуры, которая имеет желаемый макет.

GCHandle может использоваться только в том случае, если управляемые и неуправляемые макеты памяти одинаковы, поэтому можно использовать одну и ту же память.

+0

Можете ли вы привести пример моего дела? –

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

  • Нет связанных вопросов^_^