Page 1 of 1

How to put a DLL written in PB into a VC project?

Posted: Wed Jun 30, 2004 1:58 pm
by sonic3d
I wrote a little dll in to send info to a server(written in PB,too),and I wrote a test program in PB again to prove if the dll is working.Now it works well,but how can I write a program in Visual C++ that using this dll correctly?Would some one show me a way to solve it.(Static loading or Dynamic loading)

Thank a lot! :)

Here is the working DLL source:

Code: Select all

  ProcedureDLL.l GetConnID(IP$,Port.l)
    ConnID = OpenNetworkConnection(IP$, Port)
    ProcedureReturn ConnID
  EndProcedure
  ; This procedure is called once, when the program loads the library
  ; for the first time. All init stuffs can be done here (but not DirectX init)
  ;
  ProcedureDLL AttachProcess(Instance)
    If (InitNetwork()=0)
      MessageRequester("Error", "Can't initialize the network !Won'tsend log info!", 0)
    EndIf
  EndProcedure
  
  ; Called when the program release (free) the DLL
  ;
  ProcedureDLL DetachProcess(Instance)
  EndProcedure
  
  ; Both are called when a thread in a program call or release (free) the DLL
  ;
  ProcedureDLL AttachThread(Instance)
  EndProcedure
  
  ProcedureDLL DetachThread(Instance)
  EndProcedure
  
  
  ; Real code start here..
  ;
  
  ProcedureDLL.l ShuLoger(ConnID,LogMessage.s,PlayerNum.w)
    If ConnID
      SendNetworkString(ConnID, "Player:"+Str(PlayerNum)+" "+LogMessage+".")
      MessageRequester("Send OK", "Send OK", 0)
      ProcedureReturn 1
    Else
      ;MessageRequester("C-S Communicate Error !", "Can't find the server (Is it launched ?).", #MB_ICONINFORMATION)
      ProcedureReturn -2
    EndIf
  EndProcedure
  

And here is the main source of server:

Code: Select all

IncludeFile "Common.pb"

Open_Window_0()

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf
Port = 6666
Buffer = AllocateMemory(1000)
If CreateNetworkServer(Port)
  MessageRequester("PureBasic - Server", "Server created (Port "+Str(Port)+").", 0)
  Repeat
    Event = WindowEvent()
    If Event = #PB_EventGadget
      ;Debug "WindowID: " + Str(EventWindowID())
      GadgetID = EventGadgetID()
      If GadgetID = #Listview_0
        Debug "GadgetID: #Listview_0"
      ElseIf GadgetID = #Listview_1
        Debug "GadgetID: #Listview_1"
      ElseIf GadgetID = #String_0
        Port=Val(GetGadgetText(#String_0))
        Debug "GadgetID: #String_0"
      ElseIf GadgetID = #Button_0
        CloseNetworkServer()
        If (CreateNetworkServer(Port)=0)
          MessageRequester("ChangePort","Failed to change port(Port in Use?).",0)
          End
        Else
          MessageRequester("ChangePort","Port changed successfully!It's now port:"+Str(Port)+".",0)
        EndIf
        Debug "GadgetID: #Button_0"
      EndIf
    EndIf
    SEvent.l = NetworkServerEvent()
    If SEvent
      ClientID = NetworkClientID()
      Select SEvent
        Case 1
          AddGadgetItem (#Listview_1,-1,"A new client has connected !")
        Case 2
          ReceiveNetworkData(ClientID, Buffer, 1000)
          AddGadgetItem (#Listview_0,-1,PeekS(Buffer))
        Case 4
          AddGadgetItem (#Listview_1,-1,"A new client has disconnected !")
      EndSelect
    EndIf
  Until Event = #PB_EventCloseWindow
Else
  MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf

End
the Common source(for create windows) of server:

Code: Select all

;- Window Constants
;
Enumeration
  #Window_0
EndEnumeration

;- Gadget Constants
;
Enumeration
  #Listview_0
  #Listview_1
  #String_0
  #Text_0
  #Button_0
EndEnumeration


Procedure Open_Window_0()
  If OpenWindow(#Window_0, 309, 119, 422, 396,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered , "Log Display Server")
    If CreateGadgetList(WindowID())
      ListViewGadget(#Listview_0, 0, 0, 420, 280)
      ListViewGadget(#Listview_1, 0, 310, 420, 80)
      StringGadget(#String_0, 70, 285, 60, 20, "")
      TextGadget(#Text_0, 10, 290, 60, 15, "Listening")
      ButtonGadget(#Button_0, 140, 280, 70, 30, "SetPort")
      
      SetGadgetText(#String_0,"6666")
    EndIf
  EndIf
EndProcedure
Finally,the test program that using that dll:

Code: Select all

aaa.w=Int(Random(100))

If OpenLibrary(0, "SenderDll.dll")
  ConnID=CallFunction(0,"GetConnID","127.0.0.1",6666)
  For i=1 To 50
    CallFunction(0, "ShuLoger", ConnID, "I'm running:"+Str(i),aaa)
  Next i
  CloseNetworkConnection(ConnectionID)
Else
  MessageRequester("No Dll","Cannot load dll",0)
EndIf

No one knows?

Posted: Sun Jul 04, 2004 8:03 pm
by sonic3d
I tried to load library in VC,it finished successfully and returned a handle.But when I used function point and pass PB string by using C/C++ char*,it failed and said the ESP was not properly saved or parameter incorrected.I thought there should be other method to pass PB string from VC,anyone knows about it?

Sorry for my poor English!

Re: No one knows?

Posted: Sun Jul 04, 2004 8:43 pm
by NoahPhense
sonic3d wrote:I tried to load library in VC,it finished successfully and returned a handle.But when I used function point and pass PB string by using C/C++ char*,it failed and said the ESP was not properly saved or parameter incorrected.I thought there should be other method to pass PB string from VC,anyone knows about it?

Sorry for my poor English!
Not sure if this helps, I don't know C, but check out the dll section in the
manual:
NoahPhense copied from the manual and wrote:PureBasic allows to create standard Microsoft Windows DLL (Dynamic Linked Library). The DLL code is like a PureBasic code except than no real code should be written outside of procedure.

When writting a DLL, all the code is done inside procedures. When a procedure should be public (ie: accessible by third programs which will use the DLL), the keyword ProcedureDLL (or ProcedureCDLL if the procedure needs to be in 'CDecl' format, which is not the case of regular Windows DLL) is used instead of Procedure (and DeclareDLL or DeclareCDLL if are used instead of Declare). This is the only change to do to a program.

When this is done, select 'Shared DLL' as output format ('Compiler Option' window in the purebasic editor or /DLL switch in command line) and a DLL with the name you set (in the save-requester when using the IDE) will be created in the selected directory.
- np