Ошибка при попытке использовать функции из DLL - PullRequest
1 голос
/ 19 июня 2011

Мой код:

dll:

#include "stdafx.h"
#include <iostream.h>

extern "C" __declspec(dllexport) void F1()
{
    cout << "It works\n";
}

extern "C" __declspec(dllexport) int F2()
{
    return 154827;
}

extern "C" __declspec(dllexport) void F3(int n)
{
    cout << "It works: "<<n<<"\n";
}

extern "C" __declspec(dllexport) int F4(int n)
{
    return n+1;
}

консольное приложение:

#include "stdafx.h"
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <conio.h>

typedef void (WINAPI*f1)();
typedef int (WINAPI*f2)();
typedef void (WINAPI*f3)(int);
typedef int (WINAPI*f4)(int);

#define MAXMODULE 50

f1 F1;
f2 F2;
f3 F3;
f4 F4;

void main(int argc, char* argv[])
{
    HINSTANCE hLib=LoadLibrary("dllll.dll");

    if(hLib==NULL)
    {
        cout << "Unable to load library!" << endl;
        getch();
        return;
   }

    char mod[MAXMODULE];

   GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, MAXMODULE);
   cout << "Library loaded: " << endl;


    F1=(f1)GetProcAddress((HMODULE)hLib, "F1");
    F2=(f2)GetProcAddress((HMODULE)hLib, "F2");
    F3=(f3)GetProcAddress((HMODULE)hLib, "F3");
    F4=(f4)GetProcAddress((HMODULE)hLib, "F4");

   if((F1==NULL) || (F2==NULL) || (F3==NULL) || (F4==NULL)) {

        cout << "Unable to load function(s)." << endl;
        FreeLibrary((HMODULE)hLib);
        return;
   }

   F1();
   cout<<F2()<<endl;
   F3(1515);
   cout << F4(12) << endl;   //works now :)

   FreeLibrary((HMODULE)hLib);

   getch();

    return;
}

Вывод:

Library loaded:
154827
It works
It works: 1515

Вопросы:
1. Почему F1 отображается после F2?F1 вызывается раньше F2.
2. F3 Работает правильно, но заставляет окно всплывать дважды.Я нажимаю Игнорировать на нем.
http://s3.ifotos.pl/img/f3_hwpwapq.jpg
3. Почему F4 вообще не работает?Это поднимает исключение.

РЕДАКТИРОВАТЬ:
Теперь вопросы 2 и 3. решены.

Для 1 теперь вывод:

Library loaded:  
154827  
13  
It works  
It works: 1515  

По порядку: F2, F4,F1, F3.
Я называю их: F1, F2, F3, F4.
Почему это происходит?

Ответы [ 2 ]

2 голосов
/ 19 июня 2011

Вероятно, что ваша DLL и ваш исполняемый файл связаны с разными версиями библиотеки времени выполнения C ++.Поскольку в адресном пространстве вашего процесса теперь есть две разные версии библиотеки времени выполнения C ++, для stdout используются два отдельных буфера памяти.Поскольку вы не сбрасываете данные внутри своих функций DLL, но вы сбрасываете их в свой исполняемый файл (обратите внимание, что печать новой строки '\n' не сбрасывает, а печатает std::endl выполняет сброс), вот что происходит: вызывается

  1. F1, и "It works\n" записывается в буфер памяти libc ++ stdout вашей DLL.
  2. F2 вызывается, и154827\n записывается в буфер памяти исполняемого файла libc ++ stdout.Вызов std::endl очищает этот буфер и выводит его на консоль.
  3. F3 вызывается, и "It works: 1515\n" записывается в буфер памяти libc ++ stdout вашей DLL.
  4. F4 вызывается,и 13 записывается в буфер памяти исполняемого файла libc ++ stdout.Вызов std::endl очищает этот буфер и выводит его на консоль.
  5. Ваш процесс завершается, в результате чего ваша DLL выгружается.Как часть своей процедуры очистки, libc ++ сбрасывает свои выходные буферы, в результате чего "It works\nIt works: 1515\n" выводится на консоль.

Это исправление для того, чтобы убедиться, что вы используете тот же C ++ (и C) библиотеки времени выполнения в вашей DLL и в вашем исполняемом файле.См. эту страницу для получения подробной информации об этом - я рекомендую использовать версию DLL многопоточного выпуска (/MD опция компилятора) как для исполняемого файла, так и для DLL.

См. Также Передача потенциальных ошибокОбъекты CRT через границы DLL .

2 голосов
/ 19 июня 2011

Похоже, у вас неправильное соглашение о вызовах. Попробуйте изменить WINAPI (то есть __stdcall) на __cdecl.

typedef void (__cdecl *f1)();
typedef int (__cdecl *f2)();
typedef void (__cdecl *f3)(int);
typedef int (__cdecl *f4)(int);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...