سؤال

لدي هذه الوظيفة في Visual C++ DLL

char * __stdcall GetMessage(int id) {
char buffer[250];
.
.
.
strcpy(buffer, entry); // entry is a char * that has allocated 250 chars
return (char *)buffer;
}

أحاول استيراد هذه الوظيفة من C# بالرمز التالي

[DllImport("mydll.dll", CharSet=CharSet.Ansi)]
public static extern string GetMessage(int id);

أحاول تقديم هذا في messageBox، فهو يحتوي دائمًا على رموز غريبة في نهاية السلسلة.هل هناك أي اقتراحات حول كيفية التغلب على هذه المشكلة؟

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

المحلول

وأنا أعيد التأكيد على حقيقة أن التعليمات البرمجية C ++ غير صالح. كنت ستعود مؤشر إلى متغير محلي في إطار مكدس التي لم تعد صالحة عندما ترجع الدالة. أنه يعمل الآن هو مجرد حادث. بمجرد استدعاء وظيفة أخرى، سيتم إعادة استخدام مساحة مكدس إفساد محتوى العازلة. ويضمن هذا أن يحدث عند استدعاء هذا الرمز من C #، وP / استدعاء تنفيذ marshaller سوف الكتابة فوق إطار مكدس والفاسدين المخزن المؤقت.

ليزيد الطين بلة، وP / استدعاء marshaller سوف محاولة لتحرير المخزن المؤقت. وسوف نفترض أن المخزن المؤقت تم تخصيصها من قبل CoTaskMemAlloc ()، وندعو CoTaskMemFree () للافراج عن العازلة. والتي تفشل بصمت على نظام التشغيل Windows XP ولكن في وقت سابق تحطم البرنامج على ويندوز فيستا وما فوق.

ما هو حل واحد لمشكلتك، استخدم CoTaskMemAlloc () لتخصيص المخزن المؤقت بدلا من استخدام متغير محلي. الحل الأفضل للجميع حول ذلك هو السماح للطالب وظيفة تمرير العازلة، المراد شغلها مع السلسلة. بهذه الطريقة، يمكن للطالب أن يقرر كيفية تخصيص المخزن المؤقت وتنظيفه عند الضرورة. التوقيع وظيفة ينبغي أن تبدو هذه:

extern "C" __declspec(dllexport)
void __stdcall GetMessage(int id, char* buffer, size_t bufferSize);

استخدم strcpy_s () لملء بأمان العازلة وتجنب أي تجاوز سعة المخزن المؤقت. ان C # إعلان المطابقة يتم كما يلي:

[DllImport("mydll.dll")]
private static extern void GetMessage(int id, StringBuilder buffer, int bufferSize);

ودعا مثل هذا:

var sb = new StringBuilder(250);
GetMessage(id, sb, sb.Capacity);
string retval = sb.ToString();

نصائح أخرى

من DLL تقوم بإرجاع مجموعة من الأحرف، أي.المخزن المؤقت الموجود على المكدس داخل وظيفة GetMessage، وعندما يتم تنفيذ الإرجاع، يتم إفساد البيانات نظرًا لأن المخزن المؤقت قد انبثق من المكدس وهو محلي للمكدس أيضًا، ومن هنا تأتي الأحرف الغريبة التي تراها.هناك طريقتان يمكنك من خلالهما إصلاح ذلك، قم بتغيير إعلان متغير المخزن المؤقت ليكون مؤشرًا ثم قم بتخصيصه قبل إعادته أو إعلانه كثابت.

char *buffer;
if (!(buffer = (char *)malloc((250 * sizeof(char)) + 1)){
   // Handle the out of memory condition
}
// Now the buffer has 250 + 1 for null terminating character.

أو

static char buffer[250];

هل يمكنك أيضًا توضيح متغير مؤشر الإدخال - هل هذا عالمي؟

أتمنى أن يساعد هذا ، مع أطيب التحيات ، توم.

وحاول استخدام ب StringBuilder لنوع العودة وترك الخروج السمة محارف:

[DllImport("mydll.dll")]
public static extern StringBuilder GetMessage(int id);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top