Работа с DLL от Visual C++ из Open Watcom

Рейтинг: 0Ответов: 1Опубликовано: 15.05.2023

Пытаюсь научиться работать с DLL, созданной в VC++ (x86, 32 бита) из другого компилятора (конкретно для экспериментов взял Open Watcom, тоже 32 бита). Что-то не очень получается.

Что есть: простейшая DLL

extern "C"
{
    __declspec(dllexport) void test1()
    {
        std::cout << "sizeof(int*) = " << sizeof(int*) << "\n";
        std::cout << "test1\n";
    }
    __declspec(dllexport) void test2(int i)
    {
        std::cout << "test2(" << i << ")\n";
    }
    __declspec(dllexport) int test3(int*p)
    {
        std::cout << "test3(" << p << ")\n";
        return ++(*p);
    }
}

Компилиреем как cl /EHsc /LD /MT dll.cpp, получаем dll.dll и dll.lib.

Два варианта работы из VC++ вполне работоспособны:

extern "C" {
    __declspec(dllimport) void test1();
    __declspec(dllimport) void test2(int i);
    __declspec(dllimport) int test3(int*p);
}
int main()
{
    int i = 5;
    test1();
    test2(i);
    std::cout << test3(&i) << "\n";
    std::cout << test3(&i) << "\n";
}

с компиляцией как cl /EHsc /MT use1.cpp dll.lib

Второй вариант с динамическим подключением:

typedef void (*test1_func)();
typedef void (*test2_func)(int);
typedef int  (*test3_func)(int*);

int main()
{
    HMODULE dll;
    if ((dll = LoadLibrary("Dll.dll")) != NULL)
    {

        test1_func test1 = (test1_func)GetProcAddress(dll,"test1");
        test2_func test2 = (test2_func)GetProcAddress(dll,"test2");
        test3_func test3 = (test3_func)GetProcAddress(dll,"test3");

        int i = 5;
        test1();
        test2(i);
        std::cout << test3(&i) << "\n";
        std::cout << test3(&i) << "\n";
    }
}

Компилирую как cl /EHsc /MT use2.cpp. Тоже работает без нареканий.

В Watcom первый вариант - статическую линковку - я сделать так и не смог. то он ищет _imp_test1, то test1. Как ему пояснить, что я хочу, не знаю.

Динамическая компоновка проходит, но работать с указателем отказывается - сваливается с ошибкой обращения к памяти.

Думаю, что та же ерунда будет и при использовании других, отличных от VC++ компиляторов.

Подскажите, в чем я ошибся, и как корректно работать с DLL от VC++ из других компиляторов. Ведь как я понимаю, в Windows все DLL именно такие, от VC++. И как-то же их используют.

На всякий случай, вопрос от Harry и ответы на него я читал (собственно, код примера частично на его остнове и сделан), но здесь же я просто обращаюсь к месту в памяти, а не работаю с менеджером?

Ответы

▲ 0Принят

Как выяснил путем экспериментов, все работает, если добавить к каждой функции cdecl... Спасибо за намеки в комментариях!