سؤال

أواجه صعوبة حقًا في الحصول على هذا التنقل.

لدي رمز udmenaged الذي يبدو هكذا:

WORD HLP_GetDeviceNames (LPSTR *DevNames, WORD Max_Len, WORD Max_Num)

فقط لمعلوماتك لم أكتب هذا الرمز غير المدير ولكن يجب استخدامه.

إرجاع: كلمة تشير إلى خطأ.

DevNames: مؤشر إلى مجموعة من صفائف Char. أساسا مجموعة من الأوتار التي سيتم تعديلها وإعادتها إلي!

max_len: طول كل سلسلة (قيل لي أن هذا يجب أن يكون 256)

max_num: طول الصفيف. أنا أستخدم مكالمة أخرى في استدعاء تعمل تخبرني عدد الأجهزة حتى أعرف بالضبط عدد الأوتار التي يجب إرسالها.

لقد استخدمت p/invoke interop interureatoroolkit لمعرفة الكثير من هذا ولكن اقرأ أيضًا حفنة لمزيد من المعلومات. أين أنا الآن هنا:

[DllImport("UsbMeasLib.dll")]
public static extern ushort HLP_GetDeviceNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] ref StringBuilder[] DevNames, ushort Max_Len, ushort Max_Num);

أدعو الرمز الخاص بي مثل هذا:

StringBuilder[] DevNames = new StringBuilder[deviceCount];
     for(int i = 0; i< deviceCount; i++)
     {
           DevNames[i] = new StringBuilder().Append(' ', 256);
     }

     HachUsbMeasLib.HLP_GetDeviceNames(ref DevNames, 256, Convert.ToUInt16(DevNames.Count())); 

أنا أستخدم مجموعة String Builder لأنني بحاجة إلى الكود غير المُدار لتعديل منشئ السلسلة بحيث يمكنه إرجاع السلسلة الجديدة نظرًا لأن السلسلة غير قابلة للاستمتاع.

عندما أقوم بتشغيل الكود ، فإن صفيف بلدي غير معدّل!

لست متأكدًا حقًا مما يجري ، لكنني أعتقد أن الأمر يتعلق بـ CLR الذي يخبر الرمز غير المُصنّع لعدم تعديل صفيف بلدي في مكانه ولكن بدلاً من ذلك يخلق مرجعًا جديدًا (مؤشر). حتى لو كان هذا هو الحال ، لا أعرف كيفية إصلاحه.

شكرا على أي رؤية يمكن لأي شخص تقديمها!

هل كانت مفيدة؟

المحلول 2

أنا أحسب هذا واحد. بفضل أي شخص أجاب.

اكتشفت كيف يعمل. أنا ببساطة أقوم بتزويد مساحة الذاكرة ، لكن يجب أن أسمح للحمض بأنني أتوقع من داخل وخارج هذا الكائن حتى يسمح للرمز غير المُدار بتعديل المساحة المخصصة.

لقد فعلت ذلك مثل هذا:

[DllImport("UsbMeasLib.dll")]
private static extern ushort HLP_GetDeviceNames([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string[] DevNames, ushort Max_Len, ushort Max_Num);

يمكنني استخدام String بدلاً من String Builder لأن الرمز غير المُدار سيحل ببساطة محل السلسلة التي هي على ما يرام. أحصل على مؤشر الصفيف ، وليس سلاسل معدلة. الكود المدار هو مجرد تغيير مجموعة من المؤشرات للإشارة إلى كائنات سلسلة جديدة (على ما أظن).

int numDev = HLP_GetNumDevices();


string[] names = new string[numDev];

for (int i = 0; i < names.Length; i++)
{
    names[i] = new StringBuilder().Append(' ', 256).ToString();
}

ushort errorCode = HLP_GetDeviceNames(names, 256, Convert.ToUInt16(numDev));

أقوم بتخصيص الذاكرة للرمز غير الملموس ، ثم اترك الرمز غير المدير تشين الأوتار هناك.

هذا يعمل ولكني لا أعرف ما إذا كان لدي أي تسرب ذاكرة محتمل أو مشاكل محتملة أخرى.

نصائح أخرى

حاول العمل على مستوى منخفض. إعلان معلمة DevNames كـ intptr []. قم بإعداده بالطريقة التالية:

IntPtr[] devNames = new IntPtr[deviceCount];

for(int i = 0; i < deviceCount; i++) 
{ 
    devNames[i] = Marshal.AllocHGlobal[256];
}

تمرير هذا الصفيف إلى HLP_GetDevicenames. للتعامل مع بيانات الإخراج ، قم بتطبيق Marshal.PtrToStringansi على كل عضو في DevNames. لا تنس أن تطلق أسماء devnames [i] مع Marshal.freeHglobal في النهاية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top