Сообщение об ошибке не требует пояснений. У вас есть две функции с одинаковым именем в области видимости, и компилятор не знает, какую из них вы хотите использовать в строке 30, поскольку передаваемые параметры удовлетворяют обоим объявлениям функций.
Чтобы исправить ошибку, вы можете изменить эту строку:
DecodeDate(dat, godina, mjesec, dan);
Для этого:
System::Sysutils::DecodeDate(dat, godina, mjesec, dan);
Или это:
dat.DecodeDate(&godina, &mjesec, &dan);
Однако, в любом случае, вам следует избавиться от объявления extern
для DecodeDate()
, так как оно вообще не входит в этот код. Вы не внедряете DecodeDate()
самостоятельно, вы просто используете тот, который предоставлен RTL. Уже есть объявление для DecodeDate()
в SysUtils.hpp
, которое вы #include
вводите в своем коде. Это все, что нужно компилятору.
Просто убедитесь, что вы подключаетесь к библиотекам RTL / VCL, чтобы разрешить функцию на этапе компоновки после компиляции. Вы должны были включить поддержку VCL при создании проекта DLL. Если вы этого не сделали, заново создайте свой проект и включите его.
Кстати, существует НАМНОГО более простой способ реализации логики вашей функции - вместо того, чтобы вручную отделять TDateTime
и восстанавливать его компоненты, просто используйте функцию SysUtils::FormatDateTime()
или TDateTime::FormatString()
метод вместо, например:
UnicodeString __stdcall datum(TDateTime dat)
{
return FormatDateTime(_D("yyyy'-'mm'-'dd"), dat);
}
UnicodeString __stdcall datum(TDateTime dat)
{
return dat.FormatString(_D("yyyy'-'mm'-'dd"));
}
Тем не менее, этот код по-прежнему ошибочен, потому что небезопасно передавать не POD-типы, такие как UnicodeString
, через границу DLL, как вы делаете. Вам нужно переосмыслить дизайн своей функции DLL, чтобы использовать только безопасные для взаимодействия типы POD. В этом случае измените свою функцию на:
принять wchar_t*
в качестве ввода от звонящего и просто заполнить блок памяти нужными символами. Позвольте вызывающей стороне выделить фактический буфер и передать его в вашу DLL для заполнения:
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern "C" __declspec(dllexport) int __stdcall datum(double dat, wchar_t *buffer, int buflen)
{
UnicodeString s = FormatDateTime(_D("yyyy'-'mm'-'dd"), dat);
if (!buffer) return s.Length() + 1;
StrLCopy(buffer, s.c_str(), buflen-1);
return StrLen(buffer);
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
wchar_t buffer[12] = {};
datum(SomeDateValueHere, buffer, 12);
// use buffer as needed...
int len = datum(SomeDateValueHere, NULL, 0);
wchar_t *buffer = new wchar_t[len];
int len = datum(SomeDateValueHere, buffer, len);
// use buffer as needed...
delete[] buffer;
выделяет буфер wchar_t[]
для хранения нужных символов, а затем возвращает указатель wchar_t*
на этот буфер вызывающей стороне. Затем экспортируйте вторую функцию, чтобы вызывающий мог передать вам возвращенный wchar_t*
, чтобы вы могли его правильно освободить.
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern "C" __declspec(dllexport) wchar_t* __stdcall datum(double dat)
{
UnicodeString s = FormatDateTime("yyyy'-'mm'-'dd", dat);
wchar_t* buffer = new wchar_t[s.Length()+1];
StrLCopy(buffer, s.c_str(), s.Length());
return buffer;
}
extern "C" __declspec(dllexport) void __stdcall free_datum(wchar_t *dat)
{
delete[] dat;
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
wchar_t *buffer = datum(SomeDateValueHere);
// use buffer as needed...
free_datum(buffer);