У меня возникли некоторые проблемы с DLL на C ++, который я недавно получил от друга.
Я пытаюсь импортировать DLL в надстройку Excel VBA.
(Я использую Excel 2010 32bit и DLL скомпилирована в Visual Studio 2008)
Прежде всего я попытался импортировать его, но это не удалось с ошибкой времени выполнения 49.
Я пришел к выводу, что это, возможно, происходит из-за отсутствия объявления c ++ (__stdcal).
(Я думал, Visual Studio должна делать это автоматически, но все в порядке)
Теперь у меня есть новый dll с __stdcal в его объявлении, но методы объявлены с подчеркиванием (_) в его начале.
Поэтому, когда я пытаюсь объявить Sub, Excel говорит мне что-то вроде «недопустимого символа», есть ли возможность избежать этого без изменения файлов c ++?
'void _SaveFile(const char *FileName_);'
Declare Sub _SaveFile Lib "D:/DLL/TableController.dll" (ByRef FileName_ As String)
^
|
заранее спасибо
Вот некоторые дополнительные сведения, которые могут привести к решению моих проблем.
Теперь у меня есть код на C ++ для отладки моей проблемы …
Я все еще получаю ошибку времени выполнения 49, но средство обхода зависимостей теперь дает мне правильные имена методов (что, я думаю, довольно круто;))
Я пытался использовать ту же DLL в программе на C #.
Как я и ожидал, он работал совершенно нормально.
Вот мой код C #
это импорт:
[DllImport("JLTable.dll",CallingConvention=CallingConvention.StdCall)]
internal static extern void JLReadFile(string _FileName);
[DllImport("JLTable.dll", CallingConvention = CallingConvention.StdCall)]
internal static extern long JLGetRowCount();
и это произойдет, если я нажму кнопку
TableRunner.JLReadFile(@"D:\file.tab");
long rows = TableRunner.JLGetRowCount();
MessageBox.Show(rows.ToString());
Вот мой код в VBA
Декларация:
Declare Function JLReadFile Lib "D:/JLTable.dll" (ByRef FileName_ As String)
Declare Function JLGetRowCount Lib "D:/JLTable.dll" () As Long
И звонок:
Sub Read()
Dim path As String
path = "D:/file.tab"JLReadFile (path)
Dim count As Long
count = JLGetRowCount()
End Sub
А вот и код C ++, который я хочу вызвать.
По какой-то причине мой друг не хочет, чтобы я показывал, что именно делает код, но он все еще ведет себя так же с этим кодом.
Файл .h (JLTable_API — это что-то вроде #define JLTable_API __declspec (dllexport))
#define STDCALL
extern "C"{
JLTABLE_API void STDCALL JLReadFile(const char *FileName_);
JLTABLE_API void STDCALL JLSaveFile(const char *FileName_);
}
Файл .c ++
void STDCALL JLReadFile(const char *FileName_)
{
//log something to a file
}
long STDCALL JLGetRowCount()
{
//log something to a file
return 0;
}
Я очень благодарен за каждую подсказку, которую вы можете дать мне
И как всегда
заранее спасибо
У меня наконец есть решение.
я нашел блог, который показал мне, что я сделал не так.
Как описано, вам нужно правильное имя метода, чтобы выяснить, какой из них правильный, я использовал обходчик зависимостей.
Это наконец привело меня к этой декларации
VBA:
Declare Sub JLReadFile Lib "D:/JLTable.dll" (ByRef FileName_ As String) Alias "_JLReadFile@4" (ByRef FileName_ As String)
C ++:
void __declspec (dllexport) _stdcall JLReadFile(const char *FileName_);
Из аналогичного теста, который я запускал, вам нужно использовать ключевое слово «Alias». Чтобы было написано так: Declare Sub SaveFile Lib "D:/DLL/TableController.dll" Alias "_SaveFile" (ByRef FileName_ As String)
Кроме того, я не думаю, что вы должны передавать имя файла по ссылке, но я могу ошибаться. Прошло много времени с тех пор, как я использовал VB.
Более подробную информацию об импорте функций из динамической библиотеки, проверьте этот страница из