Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Comunicados
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Using DLLs in MDI project

moncef
Principiante
1.124 Visualizações

Iam using CVF to built an MDI project and I have a problem to call a Dialog Box written in a DLL wich is a subproject of the main project.

The source code of the DLL called BurnersClass.dll is :

integer*4 function ComponentBurner(BurnerTyp,GlobalIcon)

!DEC$ ATTRIBUTES STDCALL, REFERENCE,ALIAS :"ComponentBurner":: ComponentBurner

!DEC$ ATTRIBUTES DLLEXPORT::ComponentBurner

include 'resource.fd'

integer BurnerTyp

integer GlobalIcon

BurnerMenu%handle=CreateDialogParam(HandleAndInstance%ghInstance,IDD_Component_Tab, &

MDI_WINDOW_Current%Handle, loc(BurnerTab),0)

.......

ComponentBurner=0

return

end function ComponentBurner

!======================================================!

integer*4 function BurnerTab( hDlg,message,uParam,lParam )

!DEC$ ATTRIBUTES STDCALL, REFERENCE,ALIAS :"BurnerTab":: BurnerTab

!DEC$ ATTRIBUTES DLLEXPORT::BurnerTab

use user32

use kernel32

implicit none

include "Resource.fd"

integer hDlg

integer message

integer uparam,lparam

type (T_NMHDR) itabmessage

select case(message)

case( WM_INITDIALOG)

....

BurnerTab=1

return

case (WM_COMMAND)

select case (LOWORD(uParam))

case (IDOK,ID_ESCAPE)

....

end select

case(WM_move)

....

....

return

end select

BurnerTab=0

return

end function BurnerTab

The source code of the main program part that used this dll is :

integer*4 function BurnersPreprocessing(BurnerTyp)

!DEC$ IF DEFINED(_X86_)

!DEC$ ATTRIBUTES STDcall, ALIAS : '_BurnersPreprocessing@16' :: BurnersPreprocessing

!DEC$ ELSE

!DEC$ ATTRIBUTES STDcall, ALIAS : 'BurnersPreprocessing' :: BurnersPreprocessing

!DEC$ ENDIF

use user32

use kernel32

use comctl32

use DFWIN

use THESSGlobals

use HeatLibDrawingVar

use MDI_WindowsVar

use FuelClass

implicit none

include 'resource.fd'

integer iret

integer BurnerTyp

logical bret

integer(HANDLE) dll_handle(2)

integer(BOOL) free_status

pointer(p_ComponentBurner, ComponentBurner)

interface

integer*4 function ComponentBurner(BurnerTyp,GlobalIcon)

!DEC$ ATTRIBUTES DLLIMPORT::ComponentBurner

integer BurnerTyp

integer GlobalIcon

end function ComponentBurner

end interface

dll_handle(1) = LoadLibrary ("BurnersClass.dll"C)

if (dll_handle(1) == NULL) then

! Failure

stop

end if

p_ComponentBurner = GetProcAddress (dll_handle(1), "ComponentBurner"C)

if (p_ComponentBurner == NULL) then

! Failure

stop

end if

iret = ComponentBurner(BurnerTyp,GlobalIcon,IDD_component_tab)

BurnersPreprocessing=0

return

end function BurnersPreprocessing

When I debug the main program and I execute the line code :

BurnerMenu%handle=CreateDialogParam(HandleAndInstance%ghInstance,IDD_Component_Tab, &

MDI_WINDOW_Current%Handle, loc(BurnerTab),0)

I receive the message : Unhandelded exception in Main.exe (called BurnersClass.dll):0x000005:Acces Violation.

And inside the DLL when I check the values of the function BurnerTab arguments : hDlg message, uParam, lParam I obtains :

hDlg = Undefined Adress

message = Undefined Adress

uParam = Undefined Adress

lParam = Undefined Adress

If you have a solution, or a simple example of using DLL with MDI project send it me

thanks in advance

0 Kudos
10 Respostas
Jugoslav_Dujic
Contribuidor valorado II
1.124 Visualizações
Quoting - moncef

Iam using CVF to built an MDI project and I have a problem to call a Dialog Box written in a DLL wich is a subproject of the main project.

The source code of the DLL called BurnersClass.dll is :

integer*4 function ComponentBurner(BurnerTyp,GlobalIcon)

...

iret = ComponentBurner(BurnerTyp,GlobalIcon,IDD_component_tab)


I don't think that it has anything to do with MDI, and even dll could easily be a red herring. The symptoms match a fandango on stack rather than a dll problem.

However, I wonder: how come that the actual function ComponentBurner has 2 arguments, its INTERFACE has 2 arguments, and yet you call it with 3?
moncef
Principiante
1.124 Visualizações

Thank you for your remarks.

I corrected the number of arguments of the ComponentBurner function. however, the problem persists.

I think that the problem is the transmission of the parameters hDlg, message, Uparam, Lparam

Therese it a specialcompilations which make it possible to carry out this transfer of information between the DLL and project MDI?.

Altogether, the DLL is not other than Child window of the project MDI.
Jugoslav_Dujic
Contribuidor valorado II
1.124 Visualizações
Quoting - moncef

Therese it a specialcompilations which make it possible to carry out this transfer of information between the DLL and project MDI?.

No. It should just work if you declared everything correctly.

Further, I'm not sure if you just posted code fragments or is that really your code. For example, the previous error with wrong number of arguments should have caused a compile-time error, yet you say that you were able to run the program?

Another suspicious place is:

BurnerMenu%handle=CreateDialogParam(HandleAndInstance%ghInstance,IDD_Component_Tab, &

MDI_WINDOW_Current%Handle, loc(BurnerTab),0)


You don't have IMPLICIT NONE there, do you? And I don't see either declaration of INTERFACE to BurnerTab in the ComponentBurner. How is compiler supposed to know that loc(BurnerTab) refers to address of a function, not of a local REAL variable? You need either INTERFACE to BurnerTab, or both of these contained in a MODULE. But that doesn't have anything to do with dlls.

In short, it's difficult to say what is the error unless the posted code does not match the original one. But again, it should just work if you coded everything corrrectly.
moncef
Principiante
1.124 Visualizações

I showed only fraction of code concerned with the problem. Being given the fact that I cannot send the entirety of the code : it isnt a problem of confidentiality but it is very long. Here is a simple case which poses the same problem:

The DLL's source code:

MODULE MDIDIALOG

integer, private:: iret

Contains

integer*4 function DialgCallBack( hDlg,message,uParam,lParam )

!DEC$ ATTRIBUTES STDCALL, REFERENCE,ALIAS :"DialgCallBack":: DialgCallBack

!DEC$ ATTRIBUTES DLLEXPORT::DialgCallBack

use comctl32

use DFWIN

use user32

use kernel32

Implicit None

include 'RESOURCE.fd'

integer hDlg

integer message

integer uparam

integer lparam

select case(message)

case( WM_INITDIALOG)

DialgCallBack=1

return

case (WM_COMMAND)

select case (LOWORD(uParam))

case(IDOK)

iret=1

end select

DialgCallBack=1

return

end select

DialgCallBack=0

return

end function DialgCallBack

subroutine guetter(IDD_dialog)

!DEC$ ATTRIBUTES STDCALL, REFERENCE,ALIAS :"guetter":: guetter

!DEC$ ATTRIBUTES DLLEXPORT::guetter

include 'RESOURCE.fd'

integer IDD_dialog

IDD_dialog=IDD_ImportedDialog

return

end subroutine

END MODULE MDIDIALOG

Main program (MDI_UsingDlls) source code:

!**************************************************************************

! FUNCTION: MainWndProc ( hWnd, mesg, wParam, lParam )

! PURPOSE: Processes messages for the main window

! COMMENTS:

!**************************************************************************

integer function MainWndProc ( hWnd, mesg, wParam, lParam )

!DEC$ IF DEFINED(_X86_)

!DEC$ ATTRIBUTES STDCALL, ALIAS : '_MainWndProc@16' :: MainWndProc

!DEC$ ELSE

!DEC$ ATTRIBUTES STDCALL, ALIAS : 'MainWndProc' :: MainWndProc

!DEC$ ENDIF

use user32

use kernel32

use dfwbase

use MDI_UsingDllsGlobals

implicit none

integer*4 hWnd

integer*4 mesg

integer*4 wParam

integer*4 lParam

include 'resource.fd'

interface

integer*4 function AboutDlgProc( hwnd, mesg, wParam, lParam )

!DEC$ IF DEFINED(_X86_)

!DEC$ ATTRIBUTES STDCALL, ALIAS : '_AboutDlgProc@16' :: AboutDlgProc

!DEC$ ELSE

!DEC$ ATTRIBUTES STDCALL, ALIAS : 'AboutDlgProc' :: AboutDlgProc

!DEC$ ENDIF

integer*4 hwnd

integer*4 mesg

integer*4 wParam

integer*4 lParam

end function

end interface

! Variables

type (T_CLIENTCREATESTRUCT) clientcreate

type (T_MDICREATESTRUCT) mdicreate

integer*4 hwndChildWindow

integer*4 hInfo

integer*4 pInfo

type (PERWNDINFO) Info

integer*4 hActiveChild

character(SIZEOFAPPNAME) lpszTitle, lpszCaption

logical*4 lret

integer*4 ret

character(SIZEOFAPPNAME) lpszName, lpszHelpFileName, lpszContents, lpszMessage

character(SIZEOFAPPNAME) lpszHeader

integer dllDialog_handle

integer dialogH

pointer(P_DialgCallBack,DialgCallBack)

pointer(P_guetter,guetter)

interface

integer*4 function DialgCallBack( hDlg,message,uParam,lParam )

!DEC$ ATTRIBUTES DLLIMPORT::DialgCallBack

integer hDlg

integer message

integer uparam

integer lparam

end function DialgCallBack

end interface

interface

subroutine guetter(IDD_dialog)

!DEC$ ATTRIBUTES STDCALL, REFERENCE,ALIAS :"guetter":: guetter

!DEC$ ATTRIBUTES DLLIMPORT::guetter

integer IDD_dialog

end subroutine

end interface

dllDialog_handle = LoadLibrary ("DialogDll.dll"C)

if (dllDialog_handle == NULL) then

! Failure

stop

end if

P_DialgCallBack =GetProcAddress (dllDialog_handle, "DialgCallBack"C)

if (P_DialgCallBack == NULL) then

! Failure

stop

end if

P_guetter =GetProcAddress (dllDialog_handle, "guetter"C)

if (P_guetter == NULL) then

! Failure

stop

end if

!===========================================

select case ( mesg )

! WM_CREATE: Create the MDICLIENT window which contains the MDI children

case (WM_CREATE)

lpszName = "MDICLIENT"C

clientcreate%hWindowMenu = ghMenuWindow

clientcreate%idFirstChild = 1

ghwndClient = CreateWindow(lpszName, ""C, &

IOR(WS_CHILD, IOR(WS_CLIPCHILDREN, WS_VISIBLE)),&

0, 0, 0, 0, &

hwnd, NULL, ghInstance, &

LOC(clientcreate))

MainWndProc = 0

return

! WM_DESTROY: PostQuitMessage() is called

case (WM_DESTROY)

call PostQuitMessage( 0 )

MainWndProc = 0

return

! WM_COMMAND: user command

case (WM_COMMAND)

select case ( IAND(wParam, 16#ffff ) )

case(IDM_RunDialog)

call guetter(IDD_Component_Tab)

dialogH=CreateDialogParam(ghInstance,IDD_Component_Tab,&

hwnd,P_DialgCallBack,0)

ret=ShowWindow(dialogH,SW_SHOW)

MainWndProc = 0

return

case DEFAULT

MainWndProc = DefFrameProc( hWnd, ghwndClient, mesg, wParam, lParam )

return

end select

! Let the default window proc handle all other messages

case default

MainWndProc = DefFrameProc( hWnd, ghwndClient, mesg, wParam, lParam )

end select

end

When I debug the main program and I execute the line code:
dialogH=CreateDialogParam(ghInstance,IDD_Component_Tab, hwnd,P_DialgCallBack,0), likein the preceding exemple I receive the message : Unhandelded exception in Main.exe (called BurnersClass.dll):0x000005:Acces Violation. And inside the DLL when I check the values of the function BurnerTab arguments : hDlg message, uParam, lParam I obtains :

hDlg = Undefined Adress

message = Undefined Adress

uParam = Undefined Adress

lParam = Undefined Adress

It's my first experience in use of the DLLs wich contain Dialog, then thank you for your patience and your help to find a solution.


Jugoslav_Dujic
Contribuidor valorado II
1.124 Visualizações
Can you instead zip and attach the relevant files (sources, project, .rc, .h)? Here are the instructions.
moncef
Principiante
1.124 Visualizações
Quoting - Jugoslav Dujic
Can you instead zip and attach the relevant files (sources, project, .rc, .h)? Here are the instructions.

I send you the totality of the project ( MDI and DLL)
Jugoslav_Dujic
Contribuidor valorado II
1.124 Visualizações
Quoting - moncef

I send you the totality of the project ( MDI and DLL)

No you didn't (seem to). Please re-check the link above -- you probably didn't perform Step 7 ("Add as attachment")
moncef
Principiante
1.124 Visualizações
Quoting - Jugoslav Dujic

No you didn't (seem to). Please re-check the link above -- you probably didn't perform Step 7 ("Add as attachment")

Excuse me i forget to perform step 7.
Jugoslav_Dujic
Contribuidor valorado II
1.124 Visualizações
Quoting - moncef

Excuse me i forget to perform step 7.

1) You had a copy of DialogDll.dll in the root folder. Don't copy files manually -- it's a recipe for disaster when you forget to do the copying. Instead, go to Project Settings/General/Output files for the dll, and type "../Debug" (or ../Release). In this way, the dll will be automatically created in the MDI_UsingDllsDebug folder. Delete the one from the root folder

2) You don't need reference here:
!DEC$ ATTRIBUTES STDCALL, REFERENCE,ALIAS :"DialgCallBack":: DialgCallBack

3) Don't LoadLibrary on every entry to MainWndProc (it's not actively harmful, but you increase reference count to infinity). You can do it either on WM_CREATE (you need to SAVE dllDialog_handle in that case), or on IDM_RunDialog. It's nice if you also call FreeLibrary when you don't need it.
moncef
Principiante
1.124 Visualizações
Quoting - Jugoslav Dujic

1) You had a copy of DialogDll.dll in the root folder. Don't copy files manually -- it's a recipe for disaster when you forget to do the copying. Instead, go to Project Settings/General/Output files for the dll, and type "../Debug" (or ../Release). In this way, the dll will be automatically created in the MDI_UsingDllsDebug folder. Delete the one from the root folder

2) You don't need reference here:
!DEC$ ATTRIBUTES STDCALL, REFERENCE,ALIAS :"DialgCallBack":: DialgCallBack

3) Don't LoadLibrary on every entry to MainWndProc (it's not actively harmful, but you increase reference count to infinity). You can do it either on WM_CREATE (you need to SAVE dllDialog_handle in that case), or on IDM_RunDialog. It's nice if you also call FreeLibrary when you don't need it.

it works now. Thank you very much for your help.
Responder