Проблема заключается в том, как вы спроектировали свои экспортируемые функции. Библиотеки DLL - это (помимо прочего) механизм предоставления кода таким образом, чтобы его можно было использовать из приложений (или других библиотек DLL), написанных на разных языках программирования.
Посмотрите на Windows API, есть много функций, возвращающих текст. К сожалению, это делается по-разному, в Windows API нет реального стандарта. Однако я совершенно уверен, что вы не найдете ни одной функции, которая возвращает «строку» (строку Pascal или C (с нулевым символом в конце)), как вы это сделали. Причина проста: это сделает очень трудным или даже невозможным использование разных языков программирования для разных модулей. Ваша DLL будет выделять память для строки, и как только вызывающая сторона завершит работу со строкой, ей потребуется освободить память. Таким образом, оба модуля должны совместно использовать менеджер для этого фрагмента памяти. Как программа C # может использовать вашу DLL, если видит, что они используют совершенно разные менеджеры памяти?
Обычный способ получить строковое значение из DLL - это вызвать функцию с предварительно выделенным буфером и длиной буфера в параметрах, позволить функции заполнить этот буфер содержимым строки и позволить результату функции обозначать успех или неудачу. , Например, пропуск буфера недостаточного размера будет одной из причин сбоя. Разные функции Windows API справляются с этим по-разному, проще всего для вас, вероятно, определить максимальную длину строки с помощью константы, например, MAX_PATH
.
Чтобы решить вашу проблему, вы должны взять одну функцию Windows API, которую вы знаете, как вызывать из C #, и которая возвращает строковый результат в буфер, в качестве примера. Смоделируйте ваши экспортированные функции после этого примера, и их должно быть легко вызвать из программы на C #.
Edit:
Я вспомнил, что видел подобный вопрос ( Как импортировать функцию из DLL, созданной в Delphi? ) некоторое время назад, и теперь, когда я посмотрел, я обнаружил, что она также принадлежит вам. .
Тогда вы писали, что у вас нет исходного кода для этой DLL, поэтому об изменении экспортируемых функций не может быть и речи. То, что вы могли бы сделать, это создать DLL-оболочку (или COM-объект) в Delphi, вызвать оригинальный HardwareIDExtractor.dll
и предоставить разумный API поверх него. Это позволит вам одновременно предоставлять версии экспортируемых функций AnsiChar и WideChar.
Если вы хотите уменьшить беспорядок (две DLL необходимы вместо одной), вы также можете поместить исходный HardwareIDExtractor.dll
в качестве ресурса в вашу DLL-оболочку, как описано в этой публикации блога: Использование DLL, хранящихся в качестве ресурсов в программах Delphi