Пример C++ Builder 10.3 Rio Amazon Storage Service

Я пытаюсь переместить приложение, которое использует TAmazonConnectionInfo C++Builder для доступа к объектам в Amazon Simple Storage Service (S3). У меня была версия, работающая в C++Builder 10.1 Berlin, но когда я пытаюсь переместить ее в 10.3 Rio, ссылка завершается с ошибкой Unresolved external:

[Ошибка ilink32] Ошибка: неразрешенный внешний '__fastcall Data::Cloud::Amazonapi::TAmazonStorageService::GetObjectW(System::UnicodeString, System::UnicodeString, System::Classes::TStream *, Data::Cloud::Cloudapi ::TCloudResponseInfo *, Data::Cloud::Amazonapi::TAmazonRegion)'

Простейшее воспроизведение этой ошибки:

  1. Создайте новое приложение C++ Builder VCL
  2. Поместите объект TAmazonConnectionInfo и кнопку на форму и дважды щелкните кнопку
  3. Замените обработчик кликов на:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        TCloudResponseInfo * ResponseInfo = NULL;
        TAmazonStorageService *StorageService = NULL;
        TStream* stream;
        String ObjectName;
        StorageService->GetObject(ObjectName, ObjectName, stream, ResponseInfo);
    }
    

(Я понимаю, что эта процедура не будет работать, потому что ничего не инициализировано, но это приведет к ошибке ссылки с наименьшим количеством кода).

Я искал пример кода, показывающий, как это должно работать, но я не могу найти образцы кода для RAD Studio 10.3 Rio в своей системе, и не похоже, чтобы образцы были обновлены для Rio на Демонстрационный код RAD Studio на SourceForge.

Я нашел примеры на Github по адресу https://github.com/Embarcadero/RADStudio10.3Demos/tree/master/CPP, но образцы Cloud, похоже, не были перенесены для C++ Builder, только для Object Pascal.

Я пробовал добавить CloudService.lib в проект, но это не помогло. Также не добавлялось:

#pragma link "Data.Cloud.CloudAPI"
#pragma link "Data.Cloud.AmazonAPI"

Итак, есть ли работающий образец C++Builder, который компилируется и линкуется под 10.3 Rio? Как я могу заставить этот проект скомпилировать и связать?


person nachbar    schedule 18.02.2019    source источник
comment
Проблема в том, что где-то в заголовках Windows API есть небольшой #define, который заменяет GetObject на GetObjectW. Я какое-то время пытался обойти это (я не знаю, почему это не приводило к ошибке в предыдущих версиях), но пока безуспешно. тебе удалось ее решить?   -  person Rodrigo Gómez    schedule 21.02.2020


Ответы (2)


Проблема в том, что заголовок Data.Cloud.AmazonAPI.hpp включает в себя заголовок wingdi.h Windows API. В этом заголовке есть макрос, который заменяет GetObject на GetObjectA/W.

Обходной путь, который мне удалось заставить работать, заключался в том, чтобы добавить следующее в заголовок Data.Cloud.AmazonAPI.hpp, чуть ниже окончания #includes (около строки 27):

#pragma push_macro("GetObject")
#undef GetObject

Затем в конце заголовка, непосредственно перед #pragma delphiheader end. (около строки 897), добавьте следующее:

#pragma pop_macro("GetObject")

Это решает проблему с заголовками, но вам все равно придется добавить это в код, где вы хотите использовать эту функцию, чтобы она скомпилировалась, иначе она попытается скомпилировать GetObjectW, которого сейчас не существует во время компиляции.

person Rodrigo Gómez    schedule 21.02.2020

У меня такая же проблема. Я только что проверил это решение, оно работает! Спасибо!

Вы должны скопировать файл на рабочий стол, чтобы иметь возможность изменить его, а затем повторно скопировать его в каталог установки.

Добавлю, что необходимо инициализировать свойство Storage EndPoint компонента TAmazonConnectInfo именем EndPoint, который вы должны создать из своего Bucket

person Fred_W    schedule 01.09.2020