Image decoding fails when in DLL

Everything else that doesn't fall into one of the other PB categories.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Image decoding fails when in DLL

Post by Shannara »

Im sorry, but I have to bring this up as I am doing something similar ...

The following is the code for the dll:

Code: Select all

ProcedureDLL.l LoadPicture(FileName.s)
  ;This will load a PNG picture and soon do manipulation
  GM = LoadImage(#PB_Any,FileName)
  ProcedureReturn GM
EndProcedure

ProcedureDLL AttachProcess(Instance)
  UseJPEGImageDecoder()
  UseTIFFImageDecoder()
  UseTGAImageDecoder()
  UsePNGImageDecoder()
EndProcedure 
Now, what I am trying to do is load an image through the dll, and either CatchImage or CopyImage that result onto a blank image variable in the app, then free the dll image, and at last, close the library. The reason for this, is to move the 200k the Decoders add to the EXE into a DLL. Both the APP and the DLL is in PB.

How would I do that? I tried the following, but PB spits out an error claiming the return from the dll is not an initialized image, but it is ...

Code: Select all

    ;Testing ... should work?
    myLIB.l = OpenLibrary(#PB_Any, "ImageLib.dll")
    ff_Picture.l = IsFunction(myLIB, "LoadPicture")
    rt1 = CallFunctionFast(ff_Picture, "bgMenu.png")
    bgMenu.l = CatchImage(#PB_Any,UseImage(rt1))
    CloseLibrary(myLIB)


Ive tried everything, w/o the useimage, as well. Can anybody help?
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

This can't work. The Image numbers you create inside the dll are only valid inside the dll.
The main program can't know about them.
quidquid Latine dictum sit altum videtur
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

You should load your images per API. Then, you can use the handle.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Ah oki doki then, something in the new PB must of broken imaging in DLLs.

Ref: viewtopic.php?t=11407&highlight=dll

I was looking through some old posts. Something must of happened in PB between that version and this version. Thanks for the info :)
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

Shannara wrote:Ah oki doki then, something in the new PB must of broken imaging in DLLs.

Ref: viewtopic.php?t=11407&highlight=dll

I was looking through some old posts. Something must of happened in PB between that version and this version. Thanks for the info :)
It's because you are missing your globals ..

line 9 ..

main.pb

Code: Select all

Declare ChangeImage(pngFilename.s)
Declare.s GetFile()

IncludeFile "include.pb"

#dll = 1
Toggle = 0

Global ff_PNG.l ; The address in memory of the function from the library.
                ; (for CallFunctionFast)

; // letsgotothelibrary // ------------------------------------------ //
If OpenLibrary(#dll, "ImageProcessing.dll") 
  ; lets see if its a real function
  ff_PNG.l = IsFunction(#dll, "LoadPNG")
Else 
  MessageBox_(0, "could not locate dll", "DLL ERROR", #MB_SYSTEMMODAL) 
  End 
EndIf

; // start // ------------------------------------------------------- //
Open_Window_Main()

Repeat ; main loop
  Event = WaitWindowEvent()
  If Event = #PB_EventGadget
    GadgetID = EventGadgetID()
    If GadgetID = #Button_ChangeImage
      ChangeImage(GetFile())
    ElseIf GadgetID = #Button_Exit
      Event = #PB_EventCloseWindow
    EndIf
  EndIf
Until Event = #PB_EventCloseWindow

CloseLibrary(#dll) ; proper place for lib closing
End

; // ChangeImage // ------------------------------------------------- //
Procedure ChangeImage(pngFilename.s)
  rt1 = CallFunctionFast(ff_PNG, pngFilename)
  SetGadgetState(#Image_Box, UseImage(rt1))
EndProcedure

Procedure.s GetFile()
  Pattern$ = "PNG Graphic File (*.png)|*.png|All files (*.*)|*.*"
  Pattern = 0    ; use the first of the three possible patterns as standard
  File$ = OpenFileRequester("Please choose file to load", StandardFile$, Pattern$, Pattern)
  ProcedureReturn File$
EndProcedure
include.pb

Code: Select all

; PureBasic Visual Designer v3.90 build 1361

;- Window Constants
;
Enumeration
  #Window_Main
EndEnumeration

;- Gadget Constants
;
Enumeration
  #Button_ChangeImage
  #Button_Exit
  #Image_Box
EndEnumeration

Procedure Open_Window_Main()
  If OpenWindow(#Window_Main, 292, 237, 369, 223,  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered, "ImageGadget")
    If CreateGadgetList(WindowID())
      ButtonGadget(#Button_ChangeImage, 260, 20, 100, 30, "Change")
      ButtonGadget(#Button_Exit, 260, 60, 100, 30, "Exit")
      ImageGadget(#Image_Box, 10, 10, 240, 200, Image0, #PB_Image_Border)
    EndIf
  EndIf
EndProcedure
ImageProcessing.dll.pb

Code: Select all

ProcedureDLL.l LoadPNG(Filename.s)
  UsePNGImageDecoder()
  result = LoadImage(#PB_Any, Filename)
  ResizeImage(result, 240,200) ; make it fit
  ProcedureReturn result
EndProcedure 
- np
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Hmm, still no go. The resulting catched image on the return does not work. Return from Catch is 0. Cannot even use the return for any procedures or anything.
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

Shannara wrote:Hmm, still no go. The resulting catched image on the return does not work. Return from Catch is 0. Cannot even use the return for any procedures or anything.
Funny.. works great over here..

Maybe it's time you posted some code.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

I have, look at the thread starting post :) I will repost though, with the global modifications you mentioned

DLL Code:
ProcedureDLL.l LoadPicture(FileName.s)
;This will load a PNG picture and soon do manipulation
UseJPEGImageDecoder()
UseTIFFImageDecoder()
UseTGAImageDecoder()
UsePNGImageDecoder()
GM = LoadImage(#PB_Any,FileName)
ProcedureReturn GM
EndProcedure
Calling program:

;Testing ... should work?
Global myLIB.l
Global ff_Picture.l
Global bgMenu.l
Global rt1.l

myLIB = OpenLibrary(#PB_Any, "ImageLib.dll")
ff_Picture = IsFunction(myLIB, "LoadPicture")
rt1 = CallFunctionFast(ff_Picture, "bgMenu.png")
bgMenu = CatchImage(#PB_Any,UseImage(rt1))
CloseLibrary(myLIB)
Funny thing is,
bgMenu = CatchImage(#PB_Any,UseImage(rt1))
Returns image is not initalized, but if I replace UseImage(rt1) with just rt1, I do not get that message, only a zero result.
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

I think it had to do with your opening and closing the DLL again..

This will return the new handle ..

app

Code: Select all

;Testing ... should work? 
Global ff_Picture.l 

#DLL = 1

If OpenLibrary(#DLL, "ImageLib.dll") 
  ff_Picture = IsFunction(#DLL, "LoadPicture") 
  rt1 = CallFunctionFast(ff_Picture, "bgMenu.png") 
  ;bgMenu = CatchImage(#PB_Any,UseImage(rt1))
  MessageBox_(0,Str(rt1),"test",0)
Else
  End
EndIf  

CloseLibrary(#DLL) 
End
dll

Code: Select all

ProcedureDLL.l LoadPicture(FileName.s) 
;This will load a PNG picture and soon do manipulation 
UseJPEGImageDecoder() 
UseTIFFImageDecoder() 
UseTGAImageDecoder() 
UsePNGImageDecoder() 
GM = LoadImage(#PB_Any,FileName) 
ProcedureReturn GM 
EndProcedure 
And you really don't need all those global unless you have a use for them.

Also, make sure you are not running this from the debugger. Compile
it out. Make sure your image is there in the same dir as the dll and the
exe..

- np

ps - wow.. that dll got pretty fat with all those decoders in it.. ;)
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Yep, it's fat because I did not want to bloat that app's exe file. With this simple little plugin, I can add in support for various formats.

But since running in the IDE/debugger is a must for any kind of development, compiling it and running it is a big no-no for any kind of development. So .. thanks :) I'll have to post a wishlist for PB to have complete DLL support.
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

Shannara wrote:Yep, it's fat because I did not want to bloat that app's exe file. With this simple little plugin, I can add in support for various formats.

But since running in the IDE/debugger is a must for any kind of development, compiling it and running it is a big no-no for any kind of development. So .. thanks :) I'll have to post a wishlist for PB to have complete DLL support.
Yeah, do that, and crap in the other hand and wait to see what fills up
quicker..

My example works great.. You just coded it wrong. The same wrong way
you did months ago when I gave you the working example then.

- np
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

The crap comment makes no sense, are you sure you posted that in the correct thread or even forum?

You just admitted your example does not work in the debugger, now you say it works perfectly? Which one is it? For me, it does not work in the debugger, in which full dll support from IDE is needed for any kind of development of apps using dlls ... Try uncommenting CatchImage line and look at the result.

Ref: http://www.purebasic.com/documentation/ ... index.html

Unfortunately, I did not find in the manual anywhere stating DLLs will not work with programs ran in the debugger. I guess I was caught off guard. This is the first language I have ran across that does not let you use DLLs while your program is using the debugger.

As for working sample, if you mean running when compiled, that is of no use, but does show it is possible but not feasable in PB at this time (nor then). Without the ability to actually debug your program (which uses DLLs), the ability to actually fix bugs in the program is .. well .. gone.

And as we follow the path down :) The inability to fix bugs in a program, especialy show stopping bugs, renders the program useless. So unless there is the ability to use DLLs in the IDE, there is no way to actually use them and fix bugs.

Anyways, the working example worked months ago when the app is compiled, but is useless for actual development/debugging. :( I guess that is where PB debugger falls short :( The debugger does not need to care about the dll(s), only the app. Thus *maybe* the reason why it does not work with dlls, I donno.

Fred: Is there any chance you can place a blurb into the manual stating libraries (dlls) are cannot be used when debugging an app?
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

viewtopic.php?t=11407

Near the bottom of the first page was a link to a VERY simple debugger
that will debug your dll's.

As for something being built into the IDE... That would be near impossible
and even if it was there. I still wouldn't use it. Because I 'need' to know
what my dll is doing while it is in production mode. And with this simple
debugger, mentioned in the link above. I can do just that...

I can see EXACTLY what my dll doing.

- np
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Ah ha, I do not think we are thinking from the same viewpoint :) What I meant to say was, I do not need to debug my dlls at all. I only want to be able to use any dll in my pb program w/o the debugger throwing a fit :)

Thus I want to be able to OpenLibrary. CallFunctionFast, and CloseLibrary in debugger mode w/o the debugger moving things around :) That's what Ive been trying to do.
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

The debugger works just fine.

If it displays an error, then that is because you did something wrong :wink:
quidquid Latine dictum sit altum videtur
Post Reply