Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > dll


Автор: chaos 18.3.2005, 10:01
Постоянно выскакивают ошибки
вот текст длл
Код

#include <iostream.h>
#include <afx.h>

extern "C" __declspec(dllexport)
void StartCheck(int b)
{
    CString a;
    a="sadsadsad";
    cout << (LPCSTR)a << endl;
}

а вот сама программа
Код

const MAX_LEN_NAME = 100;

typedef void (WINAPI *TDllFunc)(int);

TDllFunc proba;

void test()
{
    HINSTANCE hLib=LoadLibrary("ckdb.DLL");
    if(hLib==NULL) 
    {
       cout << "Unable to load library!" << endl;
       return;
    } 

   char mod[MAX_LEN_NAME];
   GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, MAX_LEN_NAME);
   cout << "Library loaded: " << mod << endl;
   proba=(TDllFunc)GetProcAddress((HMODULE)hLib, "StartCheck");

    proba(5);
    FreeLibrary((HMODULE)hLib);
}


народ подскажите в чем тут дело

Автор: NiJazz 18.3.2005, 10:21
chaos
Чтобы узнать, на какой строке вылетает, сделай отладку.

Автор: chaos 18.3.2005, 11:06
я думаю что проблема в передаче параметров те в последовательности
stdcall...

Автор: kometa_triatlon 5.5.2005, 14:29
Блин, та же ошибка smile
Если конкретнее:

"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."

Появилась она когда заменил
typedef void (WINAPI* cfunc)(); на typedef void (WINAPI* cfunc)(int, int, int);
Причем выскакивает как раз перед FreeLibrary.
???
Да, и еще.
Код

typedef void (WINAPI* cfunc)(int, int, int);

void CMainFrame::OnRun()
{
    CAttribDlg dlg;
    if( dlg.DoModal() == IDOK){
        m_hLib=LoadLibrary("lab7dll.dll");
        if(m_hLib==NULL) 
        {    
            AfxMessageBox("Unable to load library");
            return;
        }
        GetModuleFileName((HMODULE)m_hLib, m_strMod, 50);
       

        cfunc CreateLabirint;
        
        CreateLabirint=(cfunc)GetProcAddress((HMODULE)m_hLib, "CreateLabirint");
     
        if(CreateLabirint==NULL) 
        {
        AfxMessageBox("Unable to load function");
        FreeLibrary((HMODULE)m_hLib);
        return;
        }
        CreateLabirint((int)dlg.m_iEntrNum, (int)dlg.m_iExitNum ,dlg.m_sliderRarity.GetPos());

        FreeLibrary((HMODULE)m_hLib);
        //Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
    }
}

То есть в диалоговом окне выбираю параметры, затем передаю в функцию.
m_iEntrNum и m_iExitNum - тип DWORD, m_sliderRarity - slider control
Если в СreateLabirint передать константы, например СreateLabirint(5,5,4); то работает нормально (то есть выскакивает только одна ошибка =) ), а если так, как здесь сделано, то получается пугающий Abort. smile
Интересно, почему? Какая разница?

Автор: Nastya 5.5.2005, 15:07
Пройдись в самой функции по отладке.
Возможно гд-то внутри была некорректная работа с памятью и нарушился стек или что-то еще

Автор: Fantasist 7.5.2005, 19:18
Цитата(chaos @ 18.3.2005, 07:01)
extern "C" __declspec(dllexport)
void StartCheck(int b)


Цитата(chaos @ 18.3.2005, 07:01)
typedef void (WINAPI *TDllFunc)(int);
TDllFunc proba;



А вы в курсе, что extern "C" - это cdecl, а WINAPI - это stdcall?


kometa_triatlon покажи,, как ты функцию CreateLabirint объявляешь в dll.


Автор: kometa_triatlon 8.5.2005, 00:38
Код

// lab7dll.h : main header file for the lab7dll DLL
//

#pragma once
#include <afxwin.h>

#ifndef __AFXWIN_H__
    #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"        // main symbols


// Clab7dllApp
// See lab7dll.cpp for the implementation of this class
//


class Clab7dllApp : public CWinApp
{
public:
    Clab7dllApp();

// Overrides
public:
    virtual BOOL InitInstance();
    DECLARE_MESSAGE_MAP()
};

extern "C" __declspec(dllexport) 
int CreateLabirint(int entrNum, int exitNum, int rarity);


Код

// lab7dll.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include ".\lab7dll.h"
#include "Labirint.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//    Note!
//
//        If this DLL is dynamically linked against the MFC
//        DLLs, any functions exported from this DLL which
//        call into MFC must have the AFX_MANAGE_STATE macro
//        added at the very beginning of the function.
//
//        For example:
//
//        extern "C" BOOL PASCAL EXPORT ExportedFunction()
//        {
//            AFX_MANAGE_STATE(AfxGetStaticModuleState());
//            // normal function body here
//        }
//
//        It is very important that this macro appear in each
//        function, prior to any calls into MFC.  This means that
//        it must appear as the first statement within the 
//        function, even before any object variable declarations
//        as their constructors may generate calls into the MFC
//        DLL.
//
//        Please see MFC Technical Notes 33 and 58 for additional
//        details.
//

// Clab7dllApp

BEGIN_MESSAGE_MAP(Clab7dllApp, CWinApp)
END_MESSAGE_MAP()


// Clab7dllApp construction

Clab7dllApp::Clab7dllApp()
{
    // TODO: add construction code here,
    // Place all significant initialization in InitInstance
}


// The one and only Clab7dllApp object

Clab7dllApp theApp;


// Clab7dllApp initialization

BOOL Clab7dllApp::InitInstance()
{
    CWinApp::InitInstance();

    return TRUE;
}

extern "C" __declspec(dllexport) 
int CreateLabirint(int entrNum, int exitNum, int rarity){
    CLabirint Labirint(rarity);
    Labirint.setEntrances( entrNum );  
    Labirint.setExits( exitNum );          
    return Labirint.searchMaxPathNum();
    

}


Чтобы мало не показалось smile
В dll есть мой класс CLabirint, работаю с ним.

Автор: Fantasist 9.5.2005, 21:21
kometa_triatlon.

Эх-эх.... Еще раз:

Цитата(kometa_triatlon @ 7.5.2005, 21:38)
extern "C" __declspec(dllexport)
int CreateLabirint(int entrNum, int exitNum, int rarity)


Цитата(kometa_triatlon @ 5.5.2005, 11:29)
typedef void (WINAPI* cfunc)(int, int, int);


extern "C" - это cdecl (по умолчанию). WINAPI - это stdcall.


Вот это вот сообщение:

Цитата(kometa_triatlon @ 5.5.2005, 11:29)
"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."


прямым текстом указывает в чем проблема.


Автор: kometa_triatlon 10.5.2005, 17:07
Вау. А что такое? cdecl, stdcall? smile Ну не знаю, с кем не бывает smile
Ну а как же избавиться от проблемы? Что изменить?

Автор: Fantasist 10.5.2005, 17:49
Цитата(kometa_triatlon @ 10.5.2005, 14:07)
А что такое? cdecl, stdcall?


Реккомендуется посмотреть хелп. Зачем мне в него лезть и копировать сюда?


Цитата(kometa_triatlon @ 10.5.2005, 14:07)
Ну а как же избавиться от проблемы?


Поменяй либо объявление в dll на такое:

Код

__declspec(dllexport) int __stdcall CreateLabirint(int entrNum, int exitNum, int rarity)


(здесь могут возникнуть проблемы с декорацией имен и тогда нужен будет .DEF файл)

либо в ехе:

Код

typedef void (*cfunc)(int, int, int);

Автор: kometa_triatlon 10.5.2005, 21:39
Fantasist
smile Заработало
Спасибо

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