2013-10-11 3 views
0

У меня есть приложение, которое вызывает Win32 Dll, написанное на Delphi. Мое приложение разработано на C# и работает под IIS. Я могу успешно вызвать Delphi Dll для каждой версии Windows с сервера 2003 года, за исключением Windows Server 2012. Вызов внешнего метода не возвращает никаких ошибок и ничего не содержится в журнале ошибок. Он просто никогда не возвращает никаких данных.Вызов Win32 Dll из C# на Windows Server 2012

В моей C# Я заявляю:

[DllImport("MyTest.dll", CharSet = CharSet.Unicode, 
     CallingConvention = CallingConvention.StdCall)] 
    public static extern void Encrypt(string szPlainText, StringBuilder szCipherText); 

Я затем вызвать функцию со следующим:

StringBuilder encText = new StringBuilder(128); 
StringBuilder plainString = new StringBuilder("test"); 

Encrypt(plainString.ToString(), encText); 

Что-то изменилось в WinServer 2012, что бы остановить это работать?

Delphi код, который у меня есть доступ к выглядит следующим образом:

procedure Encrypt(szPlainText: PChar; szCipherText : PChar) ; stdcall ; export; 
var 
    sTemp : String ; 
    sPlainText : String ; 
    cipher : TCipher ; 

begin 
    cipher := TLogixCipher.Create ; 
    sPlainText := szPlainText ; 

    sTemp := cipher.Encrypt(sPlainText) ; 
    StrPCopy(szCipherText,sTemp);  
    FreeAndNil(cipher) ; 
end; 
+0

«Ничего не изменилось?»: Я ничего не слышал.Если у вас есть символы для компонента Delphi, вы можете включить собственную отладку и пройти через вызов P/Invoke. – Richard

+0

Просьба показать декларацию функции Delphi. Кроме того, код вызова C#, который вы представляете, является неполным. Пожалуйста, покажите больше. –

+0

У меня нет доступа к функции Delphi на данный момент. Это не то, что я разработал – keitn

ответ

2

Примечание: Этот ответ был написан, чтобы соответствовать оригинальной версии этого вопроса. Поскольку он был написан, вопрос был изменен, чтобы включить изменения, предложенные ниже.


Объявление p/invoke, вероятно, неверно для начала. Первый параметр - входной параметр (я полагаю) и поэтому должен быть объявлен как строка. Я бы объявить п/ссылаться, как это:

public static extern void Encrypt(
    string szPlainText, 
    StringBuilder szCipherText 
); 

Это не имеет никакого значения, но мало смысла в сортировочных простой текст обратно в управляемом коде, когда функция возвращает С простой текст не будет были изменены.

Вторая проблема заключается в том, что перед вызовом вам необходимо выделить буфер в параметре szCipherText.

Итак, предположим, что вы знали, что буфер нужно иметь длину 100, можно было бы написать так:

StringBuilder CipherText = new StringBuilder(100); 
Encrypt(PlainText, CipherText); 

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

StringBuilder CipherText = new StringBuilder(PlainText.Length); 
Encrypt(PlainText, CipherText); 

Обратите внимание, что вызываемая вами функция не возвращает никаких ошибок. Это не удивительно, поскольку для этого нет механизма.

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


После ваших различных обновлений код в вопросе теперь верен. Это заставляет меня подозревать, что код Delphi действительно возвращает пустую строку. В этом случае логический вывод состоит в том, что cipher.Encrypt возвращает пустую строку. Попробуйте заменить код Delphi этой функцией, чтобы протестировать интерфейс:

procedure Encrypt(szPlainText: PChar; szCipherText: PChar); stdcall; 
begin 
    StrPCopy(szCipherText, szPlainText);  
end; 
+0

Я внес изменения, которые вы предложили, но не было никакой разницы. Этот код был развернут на многих машинах без сервера 2012 без проблем. Я пробовал это на двух серверах Server 2012 в совершенно разных средах без успеха, и я думаю, что есть что-то отличное от предыдущих версий Windows. – keitn

+0

Вам нужно знать больше о вашей среде, чем вы нам сказали. Вы не дали подробного описания интерфейса, поэтому мне пришлось делать догадки. Вы на 100% уверены, что не работаете под 64 бит? И попробуйте получить некоторые диагностические данные. Код C# даже достигает вызова Encrypt? Если у вас есть функция, которая ведет себя, как я описываю в своем комментарии к вопросу, код в моем ответе - это то, как вы его называете. –

+0

Он работает в 64-битном режиме, DLL Delphi также является 64-битным. Он определенно достигает вызова, у меня есть логические заявления с каждой стороны. – keitn

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