|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Добрый день, Коллеги. Много постов перичитано но проблема все равно не поддается. Есть native dll (черный ящик). Функция со следующим объявлением в качестве параметра должна принимать строку и возвращать тоже строку. Код: plaintext 1. 2. 3.
Пытаемся подключить это к нашему проекту на C# Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Вот и на этом этапе и получаем: Cannot marshal 'return value': Invalid managed/unmanaged type combination (Int/UInt must be paired with SysInt or SysUInt). Вообщем не можем разобраться как же в итоге привести выходной параметр процедуры к строке. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 17:20 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Добавлю что если убрать [return: MarshalAs(UnmanagedType.LPStr)] то вылетает с ошибкой Unable to load DLL 'c:\native.dll': Invalid access to memory location. (Exception from HRESULT: 0x800703E6) ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:00 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjut, по аналогии с FormatMessage которая определена как Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
и импортируется как Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
попробуйте маршалить строковый параметр через StringBuilder (LPTSTR определяется как Код: plaintext 1. 2. 3. 4. 5.
если что, т.е. и LPSTR, и LPSTR - оба представляют из себя строковые указатели). ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:03 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Сон Веры Павловныvjut, по аналогии с FormatMessage попробуйте маршалить строковый параметр через StringBuilder Так проблемма не в параметре функции (тут C# не ругается), а в return параметре. А как маршалить через StringBuilder и в чем же разница? ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:26 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjut, попробуй заменить IntPtr на string. И убери unsafe. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:26 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
bazilevjut, попробуй заменить IntPtr на string. И убери unsafe.+ если заработает, то нужно будет ответить на вопрос, как освобождать память, выделенную под возвращаемую строку внутри метода LPSTR func(LPSTR IniPsw) . ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:37 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
bazilevjut, попробуй заменить IntPtr на string. И убери unsafe. пробовал, тогда падает на ошибке доступа к памяти. unsafe же нужен когда библиотека на C++ или Delphi. В лубом случае я пробовал убирать - не помогает. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:37 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Еще вариант попробовал оставить только чисто IntPtr: Код: c# 1. 2. 3. 4.
И сново валится на доступе к памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:39 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjut, out2 = func(message); ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:41 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjutЕще вариант попробовал оставить только чисто IntPtr: Код: c# 1. 2. 3. 4.
И сново валится на доступе к памяти.Вероятно неправильное описание нативного метода. Ну не возвращают так строки в нативе. Только в рамках стандарта COM, но там BSTR. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:42 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
+ ерунда написана vjut Код: c# 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:46 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjut, есть несколько утилит, генерирующих код импорта нативных методов - см. например, обсуждение здесь - попробуйте воспользоваться ими. Я в свое время пользовался P/Invoke Interop Assistant'ом, он несколько раз вполне помог. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:50 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Вариант со StringBuilder Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
выпадает с ошибкой: System.DllNotFoundException: Unable to load DLL 'c:\native.dll': Invalid access to memory location. (Exception from HRESULT: 0x800703E6) Поменяв StringBuilder на string - тот же результат. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 18:54 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjutВариант со StringBuilder.Зачем задавать вопросы и не читать ответы? ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 19:05 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Алексей КvjutВариант со StringBuilder.Зачем задавать вопросы и не читать ответы? Не совсем понял. Какой вариант Вы предлагаете еще попробовать? Вариант с Interop Assistant'ом пока тоже проверить не могу. Пытался качнуть утилиту, но в нашей сети заблокирован ресурс. И к тому же непонятно, как ему заголовочный файл рисовать. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 19:13 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjutАлексей Кпропущено... Зачем задавать вопросы и не читать ответы? Не совсем понял. Какой вариант Вы предлагаете еще попробовать?Я вообще не вижу ни одного разумного варианта с указанным прототипом метода. В лучшем случае будет работать с утечкой памяти, поскольку не описано, как освобождать память, выделенную под возвращаемую строку. Я предлагаю сделать тестовый проект на C++, там попробовать вызвать указанный метод. Обратить внимание на возможную утечку памяти. Когда оно заработает, опубликовать C++ код вызова тут, тогда будет о чём говорить. Перед всем этим лучше уточнить, правильно ли описан прототип метода: обычно в нативном C++ API память под возвращаемую строку выделяется в вызывающем методе, а не в вызываемом. Такой вызов в .Net PInvoke описывается с использованием StringBuilder, с указанием соответствующего размера буфера под строку. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 19:21 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Алексей Кvjutпропущено... Не совсем понял. Какой вариант Вы предлагаете еще попробовать?Я вообще не вижу ни одного разумного варианта с указанным прототипом метода. В лучшем случае будет работать с утечкой памяти, поскольку не описано, как освобождать память, выделенную под возвращаемую строку. Я предлагаю сделать тестовый проект на C++, там попробовать вызвать указанный метод. Обратить внимание на возможную утечку памяти. Когда оно заработает, опубликовать C++ код вызова тут, тогда будет о чём говорить. Перед всем этим лучше уточнить, правильно ли описан прототип метода: обычно в нативном C++ API память под возвращаемую строку выделяется в вызывающем методе, а не в вызываемом. Такой вызов в .Net PInvoke описывается с использованием StringBuilder, с указанием соответствующего размера буфера под строку. В варианте с IntPtr как раз память можно освободить через Marshal.FreeHGlobal. Попробовать собрать свою библиотеку с теми же типами это конечно мысль, но я плюсы уже давно в руках не держал, даже не знаю есть ли где компилятор под рукой. И если вдруг с собственной библиотекой все заработает, то никак не поможет решить проблему с черным ящиком. Стороннюю библиотеку я никак переписать не смогу. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 19:31 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjutАлексей Кпропущено... Я вообще не вижу ни одного разумного варианта с указанным прототипом метода. В лучшем случае будет работать с утечкой памяти, поскольку не описано, как освобождать память, выделенную под возвращаемую строку. Я предлагаю сделать тестовый проект на C++, там попробовать вызвать указанный метод. Обратить внимание на возможную утечку памяти. Когда оно заработает, опубликовать C++ код вызова тут, тогда будет о чём говорить. Перед всем этим лучше уточнить, правильно ли описан прототип метода: обычно в нативном C++ API память под возвращаемую строку выделяется в вызывающем методе, а не в вызываемом. Такой вызов в .Net PInvoke описывается с использованием StringBuilder, с указанием соответствующего размера буфера под строку. В варианте с IntPtr как раз память можно освободить через Marshal.FreeHGlobal.Откуда такая уверенность? Или есть информация об используемом менеджере памяти внутри нативной библиотеки? Конечно можно попробовать так, но гарантий никаких: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
29.07.2015, 20:05 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
vjutВ варианте с IntPtr как раз память можно освободить через Marshal.FreeHGlobal. а может быть ворона, а может быть лисица.... а может быть FreeCoTaskMem, а может FreeBSTR как вариант - возвёрнутая память не должна освобождаться вызывающим ... |
|||
:
Нравится:
Не нравится:
|
|||
30.07.2015, 02:06 |
|
LPSTR from DLL into NET
|
|||
---|---|---|---|
#18+
Изопропил, Для начала хотелось бы разобраться с доступом к памяти, а потом уже подумаем об ее освобождении. Сейчас же все что мы получаем - это ошибка доступа. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.07.2015, 08:33 |
|
|
start [/forum/topic.php?fid=20&msg=39019024&tid=1401243]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
36ms |
get topic data: |
8ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
others: | 333ms |
total: | 469ms |
0 / 0 |