Имам dll, написан на C++, който се експортира така:
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);
}
В моя vb6 dll декларирах дистанционното повикване по следния начин:
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, за да се уверя, че не е това проблемът, и получих грешка, че не може да намери файла, така че знам, че не е това. Нещо друго, което трябва да направя, за да заработи?
РЕДАКТИРАНЕ: Промяната на типа променлива според отговора на xxbbcc по-долу позволи това да функционира правилно. Това обаче създаде нов, засега напълно неразрешим проблем. Създадох друг въпрос тук, който има някои от подробности за него.
Отдалеченото повикване се извършва в COM+ dll, вътре във функция, която връща тип integer
към друга не-COM dll. По някаква странна причина функцията на 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