2015-01-16 2 views
1

Итак, справочная информация: я пытаюсь выдать команды внешнему устройству (а именно, анализатору импеданса, AIM 4170D) и ему была предоставлена ​​dll для предоставления командного интерфейса между кодом C# и самим устройством. У меня нет кода для dll. По общему признанию, я даже не знаю, на каком языке была написана dll. Имена самих команд, а также аргументы были даны документацией, поставляемой с dll. В документации также указано, что строка никогда не будет превышать 255 байт.Как правильно вернуть строку из неуправляемой сторонней DLL в C#?

Я постоянно получаю сообщение об ошибке «Попытка чтения или записи защищенной памяти. Это часто свидетельствует о том, что другая память повреждена». при попытке получить строку из dll. Я признаю, что это предположение, но две команды dll, которые я могу запустить до запуска AIM_GetVersion, оба из которых возвращают ints, отлично работали (не только не возвращали ошибок, а получали ответ от устройства). То, что я читал до сих пор, говорит о том, что работа со строками из dll может быть проблематичной, но также предполагает, что у меня есть доступ к исходному коду dlls для решения проблемы.

Первая попытка:

[DllImport(@"AIM_863_DLL.dll", CallingConvention = CallingConvention.StdCall)] 
public static extern string AIM_GetVersion(int flag); 

string ver = AIM_GetVersion(1); 

Вторая попытка:

[DllImport(@"AIM_863_DLL.dll", CallingConvention = CallingConvention.StdCall)] 
public static extern IntPtr AIM_GetVersion(int flag); 

IntPtr ver = Marshal.AllocHGlobal(255); 
ver = AIM_GetVersion(1); 
Marshal.FreeHGlobal(ver); 

Обе попытки получил ту же ошибку (как описано выше) при вызове AIM_GetVersion. Если я попытаюсь запустить второй набор, когда устройство выключено, я получаю сообщение об ошибке «Недопустимый доступ к ячейке памяти». на FreeHGlobal. (Хорошо, я попробовал больше двух вещей, но попытка «второго» была единственной, которая была обнаружена, что вызвало изменение в поведении программы. Я представил ее здесь, если бы он мог сузить вопрос.)

Кроме того, я скомпилирую его с помощью VS2010 с использованием x86.

Благодарим за помощь, которую вы можете предоставить. Кроме того, я новичок в этом, поэтому, если я оставил все, что может быть полезно, я предоставлю его, если это возможно.

Редактировать: Хорошо, я добавляю все соответствующие коды к этой функции, которые я получил от третьей стороны здесь. В верхней части кода просто перечисляются:

EXPORT AIM_GetVersion 

И далее фактическую функцию (которая просто вызывает другую функцию глубже в библиотеке DLL не было дано):

' External command for DLL: 
SUB AIM_GetVersion(flag:int),string 
extcmnd=1 
runmode=1 
Get_Version(0) 

extcmnd=0 
if error : s1="34506" : endif 
RETURN s1 
EndSub 

If I нужно больше информации, я могу снова спросить компанию, но я не совсем уверен, что еще просить.

+3

Мы понятия не имеем, что такое подпись неуправляемой функции. Пожалуйста, сообщите нам об этом. В противном случае мы догадываемся. –

+0

Хотя я могу сказать, что ваши попытки C# ошибочны. Я просто не могу сказать вам, что правильно, пока я точно не знаю, что такое неуправляемая функция. –

+0

Хорошо, я добавил дополнительную информацию в качестве редактирования основного сообщения. – excalibrations

ответ

2

Ваш Marshal.AllocHGlobal() вызов просто утечки памяти, удалить это. Вы не можете вызвать Marshal.FreeHGlobal(), вероятность того, что строка была выделена в куче процесса, является незначительной. C-код, подобный этому, обычно возвращает литеральную строку, она не должна и не может быть выпущена.

Просто позвоните Marshal.PtrToStringAnsi(), чтобы преобразовать IntPtr в строку, ничего больше. Напишите небольшую тестовую программу, которая делает это в миллиард раз, вы будете чувствовать себя намного лучше, когда она не взорвется.

+0

Я сделал то, что вы предложили. Когда устройство выключено, я получаю правильный код ошибки из dll. Однако, когда он включен, я все равно получаю «Попытка читать или записывать защищенную память. Это часто свидетельствует о том, что другая память повреждена». ошибка. – excalibrations

+0

Я не могу догадаться, как строка превратилась в код ошибки. Обратитесь к владельцу DLL для получения поддержки. –