Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > вызов функции из dll


Автор: kerser 26.4.2008, 10:13
Функция в dll должна вызвать функцию, которая находится в windows-приложении. Т. е.

bool func()
 {
  double pr=1.2;
  if (asd(pr)) //функция в windows-приложении
   return 1;
  else
   return 0;
 }

В windows-приложении:
bool asd(double pr)
 {
   return 1;
 }

При компиляции выдаются ошибки:
 [Linker error] undefined reference to `_Z10asdd@8'
 ld returned 1 exit status 
 c:\Dev-Cpp\KT\Makefile.win [Build Error]  [Ktdll.dll] Error 1

ide - dev-c++

Автор: xvr 28.4.2008, 10:44
Передать функцию asd из приложения в dll при инициализации последней. Явный экспорт функций из exe в dll невозможен (IMHO).
Можно еще попробовать динамически через GetProcAddress(GetModuleHandle(NULL),"asd").
Но функция asd в таком случае должна экспортироваться из exe (например через __declspec( dllexport) )



Автор: kerser 29.4.2008, 18:22
Цитата

Можно еще попробовать динамически через GetProcAddress(GetModuleHandle(NULL),"asd").
Но функция asd в таком случае должна экспортироваться из exe (например через __declspec( dllexport) )

Есть приложение proc5. В нем вызываю ф-цию func из dll:
case WM_PAINT:
 {
   PAINTSTRUCT ps;
   char str[3];
   int a=func(12);    // функция func находится в dll 
   wsprintf(str, "%d", a);
   HDC hDC=BeginPaint(hwnd, &ps);
   TextOut(hDC, 10, 10, str, 3);
   EndPaint(hwnd, &ps);  
   break;  
  }

В dll в ф-ции func вызываю ф-цию qw, которая находится в приложении qwert:
int func(int k)
 {
  typedef int (*ggg) (int);
  HMODULE hm=GetModuleHandle("qwert.exe");
  ggg aaa=(ggg)GetProcAddress(hm, "qw"); // функция qw находится в приложении qwert
  k=k+7;
  if (aaa!=0)
   {
    k=aaa(k);
   }
  return k;
 }

В qwert.h:
__declspec(dllexport) int __stdcall qw(int);

В qwert.cpp:
int qw(int k)
 {
  k=k+1000;
  return k;
 }

Ошибка в том, что ф-ция GetModuleHandle возвращает 0. Подскажите, пожалуйста, как исправить.

Автор: xvr 29.4.2008, 20:59
Цитата(kerser @ 29.4.2008,  18:22)
Цитата

Можно еще попробовать динамически через GetProcAddress(GetModuleHandle(NULL),"asd").
Но функция asd в таком случае должна экспортироваться из exe (например через __declspec( dllexport) )

Есть приложение proc5. В нем вызываю ф-цию func из dll:
case WM_PAINT:
 {
   PAINTSTRUCT ps;
   char str[3];
   int a=func(12);    // функция func находится в dll 
   wsprintf(str, "%d", a);
   HDC hDC=BeginPaint(hwnd, &ps);
   TextOut(hDC, 10, 10, str, 3);
   EndPaint(hwnd, &ps);  
   break;  
  }

В dll в ф-ции func вызываю ф-цию qw, которая находится в приложении qwert:
int func(int k)
 {
  typedef int (*ggg) (int);
  HMODULE hm=GetModuleHandle("qwert.exe");

Нужно GetModuleHandle(NULL) - вернет handle приложения

Цитата

 ggg aaa=(ggg)GetProcAddress(hm, "qw"); // функция qw находится в приложении qwert

В qwert.h:
__declspec(dllexport) int __stdcall qw(int);

В qwert.cpp:
int qw(int k)
В GetProcAddress функция будет называться не qw а гораздо замысловатее - сработает C++ mangling имен, окружи
__declspec(dllexport) int __stdcall qw(int); скобками extern "C" :
Код

extern "C" {
__declspec(dllexport) int __stdcall qw(int);
}
После этого функция все равно не будет qw, а будет _qw@4, это имя и подавай в GetProcAddress

Автор: kerser 29.4.2008, 21:40
Переделал так
В dll:
Код

int func(int k)
 {
  typedef int (*ggg) (int);
  HMODULE hm=GetModuleHandle(NULL);
  ggg aaa=(ggg)GetProcAddress(hm, "_qw@4");
  k=k+7;
  if (aaa!=0)
   k=aaa(k);
  return k;
 }

В qwert.h
Код

extern "C" {__declspec(dllexport) int __stdcall qw(int);}

GetProcAddress возвращает 0, не пойму, где ошибка

Автор: 586 29.4.2008, 22:40
Таблицу экспорта не дано посмотреть?

Автор: kerser 1.5.2008, 15:09
С помощью dumpbin смотрю таблицу импорта dll (хотя я ее и не вижу):
Код


Dump of file c:\dev-cpp\libget.a

File Type: LIBRARY

  Summary

           0 .bss
           0 .data
          14 .idata$2
          10 .idata$4
          10 .idata$5
          1C .idata$6
          10 .idata$7
          10 .text



Таблица экспорта dll, но здесь все нормально, dll экспортирует функцию func:
Код


Dump of file c:\dev-cpp\libget.a

File Type: LIBRARY

     Exports

       ordinal    name

                  __Z4funci@4
                  __Z4funci

  Summary

           0 .bss
           0 .data
          14 .idata$2
          10 .idata$4
          10 .idata$5
          1C .idata$6
          10 .idata$7
          10 .text


Таблица экспорта приложения qwert (ее тоже нет):
Код


Dump of file c:\dev-cpp\qwert.exe

File Type: EXECUTABLE IMAGE

  Summary

        1000 .bss
        1000 .data
        1000 .idata
        1000 .rdata
        1000 .text


Т. е. получается, что функция qw не импортируется в длл, и не экспортируется из приложения?
GetProcAddress возвращает 0. Подскажите, пожалуйста, что не правильно.

Автор: 586 1.5.2008, 15:38
Значит, в приложении дело.
Цитата(kerser @  29.4.2008,  19:22 Найти цитируемый пост)
В dll в ф-ции func вызываю ф-цию qw, которая находится в приложении qwert:
int func(int k)
 {
  typedef int (__stdcall*ggg) (int);
  HMODULE hm=GetModuleHandle("qwert.exe");
  ggg aaa=(ggg)GetProcAddress(hm, "qw"); // функция qw находится в приложении qwert
  k=k+7;
  if (aaa!=0)
   {
    k=aaa(k);
   }
  return k;
 }

В qwert.h:
extern "C" __declspec(dllexport) int __stdcall qw(int);

В qwert.cpp:
int __stdcall qw(int k)
 {
  k=k+1000;
  return k;
 }

Автор: kerser 3.5.2008, 06:46
Таблица экспорта приложения qwert, где находится функция, которую надо вызвать из dll:

Код

Dump of file c:\dev-cpp\qwert.exe

File Type: EXECUTABLE IMAGE

  Section contains the following exports for qwert.exe

           0 characteristics
    4819F967 time date stamp Thu May 01 20:09:59 2008
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001472 qw@4

  Summary

        1000 .bss
        1000 .data
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .text



А вот таблицы импорта dll нет, чего я только уже не делал.

Автор: xvr 3.5.2008, 08:50
Цитата(kerser @ 3.5.2008,  06:46)
Таблица экспорта приложения qwert, где находится функция, которую надо вызвать из dll:

Код

Dump of file c:\dev-cpp\qwert.exe

File Type: EXECUTABLE IMAGE

  Section contains the following exports for qwert.exe

           0 characteristics
    4819F967 time date stamp Thu May 01 20:09:59 2008
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001472 qw@4

  Summary

        1000 .bss
        1000 .data
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .text



О! Экспорт уже появился (только почему то без подчеркивания).
Цитата

А вот таблицы импорта dll нет, чего я только уже не делал.
При runtime связывании через GetProcAddress ее и не будет. Только в GetProcAddress надо подавать имя "qw@4", а не "_qw@4"

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)