У меня есть dll, написанная на С++, которая экспортируется так:
extern "C" {
extern _declspec(dllexport) (VOID) Merge(LPCSTR szFileName, LPCSTR szMergeString, DWORD dwAlignment, BOOL fRepeat);
}
Эта функция определена в другом месте как:
extern _declspec(dllexport) (VOID) Merge(LPCSTR szFileName, LPCSTR szMergeString, DWORD dwAlignment, BOOL fRepeat)
{
Tools::Merge(gcnew String(szFileName), gcnew String(szMergeString), dwAlignment, fRepeat == TRUE);
}
В моей dll vb6 я объявил удаленный вызов следующим образом:
Private Declare Sub Merge Lib "Tools.dll" (fileName As String, mergeString As String, Alignment As Long, repeated As Boolean)
Затем я вызываю это в коде следующим образом:
Merge strPageFileName, "COPY", 5, True
Когда я запускаю приложение, я получаю «Ошибка автоматизации: сбой удаленного вызова процедуры» в окне сообщения.
Tools.dll
находится в C:\Windows\system32. Я проверил с неверным именем dll, чтобы убедиться, что это не проблема, и получил сообщение об ошибке, говорящее о том, что файл не найден, поэтому я знаю, что это не так. Что-нибудь еще мне нужно сделать, чтобы заставить это работать?
EDIT: Изменение типа переменной в соответствии с ответом xxbbcc ниже позволило этому работать правильно. Однако это породило новую, до сих пор совершенно неразрешимую проблему. Я создал еще один вопрос здесь, в котором есть некоторые из подробности об этом.
Удаленный вызов происходит в dll COM+ внутри функции, которая возвращает тип integer
в другую dll, отличную от COM. По какой-то странной причине функция COM+ dll теперь возвращает вариант типа VT_ERROR
вместо целого числа. Я тщательно проверил это и определил, что не имеет значения, что я делаю с возвращаемым значением заранее, устанавливая для него любое значение и т. Д., Он всегда возвращает ошибку. Нечетная часть заключается в том, что значение ошибки, по-видимому, равно 0. Я вызвал CInt(returnValue)
, CStr(returnValue)
и CLng(returnValue)
, и они возвращают 0
, Error 0
и 0
соответственно.
Мне не удалось найти никакой информации, объясняющей, почему функция, которая должна возвращать целое число, вдруг вместо этого возвращает ошибку. Это дает мне ошибку несоответствия типа в функции, отличной от COM+, поскольку она пытается присвоить возврат локальному целому числу. Изменение этого на вариант позволило мне сделать указанные выше приведения. Вызов VarType(returnValue)
дает 10, то есть vbError
. Мы не хотим потенциально терять информацию об ошибках из других вызовов внутри dll COM+, поэтому я не могу просто игнорировать возвращаемое значение.
dumpbin /exports
, чтобы убедиться, что ваша экспортированная функция называется именно так, как ее ищет ваш клиент VB6? (То есть, полностью ли имя функции не искажено в DLL?) Еще одна вещь, которую нужно проверить: действительно ли вызывается ваша функция C++? Если вы поставите в него точку останова, он сработает? - person xxbbcc   schedule 11.05.2013Merge
, как и следовало ожидать. Проблема с отладкой заключается в том, что она находится на сервере, и нет удобного способа отлаживать ее или тестировать на моем ПК. Я попытался сделать это наоборот, с помощью regasm и запуская это как COM-dll, и таким образом выдается ошибка 438, указывающая, что он не может найти функцию. - person Joe M   schedule 11.05.2013regasm
илиregsvr32
? Если это простая C/C++ DLL, regasm ничего не сделает. Кроме того, вы не можете экспортировать простые функции в COM без библиотеки типов — у вас есть такая для вашей DLL? (Таким образом вы можете экспортировать глобальные функции в VB6, но тогда потребуется библиотека типов.) - person xxbbcc   schedule 11.05.2013Tools.Merge
в VB6, но я сомневаюсь, что он там есть (никогда не пробовал). Для вашей глобальной функцииMerge
используйте файл DEF для ее экспорта, и тогда VB6 сможет ее вызвать. Вам все еще нужно исправить свое заявлениеDeclare
в соответствии с моим ответом. Прямо сейчас вы пытаетесь вызвать свою функцию с неправильными параметрами. - person xxbbcc   schedule 13.05.2013s (HRESULTs) and that an scode could indicate error or success? A VbError of 0 is the scode/HRESULT called
S_OK`, стандартный код COM для успешного завершения. - person Euro Micelli   schedule 17.05.2013