Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to compile 32 bit dll 1

Status
Not open for further replies.

Jan Flikweert

Programmer
Mar 20, 2022
85
NL
Hi all,

I know VFP cannot handle 64-bit com DLLS.

I supposed using a dll from a x86 distibution will run on VFP.

That does not work.
Naamloos_np2tri.jpg


And here the print screen of Dependencies(x64)
Naamloos1_k4u60e.jpg

I used the code
Code:
DECLARE INTEGER new_fluid_settings IN .\binx86\libfluidsynth-3.dll
setting=new_fluid_settings()

I suppose the source should be compiled 32-bit in a way VFP can handle this.

Kind regards,

Jan Flikweert

How to do that in Visual Studio/CMake?

Of course I am going to look in other communities, going to google, but if some one knows it?

Kind regards,

Jan Flikweert
 
Visual Studio has a switch for that, platform target. x86=32bit x64=64bit.
There is a 32bit Dependency Walker version. You should use that to find out anything that is meaningful for VFP.

Chriss
 
And if it's an assembly DLL you'll never be able to load it with DECLAREs, no matter if 32bit or not.

Chriss
 
Chriss,

Thanks for your reply. This is very valuable. I am confused with WINAPI's.

Chris Miller said:
you'll never be able to load it with DECLAREs

It is the same as creating and running a com server in VFP:

Code:
Try
	css=Createobject('dll_gmnt_dag.import_gmnt_dag ')
	css.begin()

Code:
CLOSE ALL
CLEAR ALL
CLEAR DLLS

IF FILE("dll_gmnt_dag.dll")
   DECLARE integer DllUnregisterServer IN dll_gmnt_dag.dll
   DllUnregisterServer()
   CLEAR DLLS
ENDIF

BUILD PROJECT dll_gmnt_dag FROM .\dll_gmnt_dag.prg
BUILD mtDll dll_gmnt_dag from dll_gmnt_dag recomp

DEFINE CLASS import_gmnt_dag AS Session OLEPUBLIC

 
Joe,

Thanks for your reply.

jlcca said:
I am able to use 64-bit COM dlls from 32-bit, and 32-bit COM dlls from 64-bit.

That will not work because these dll's do not appear in the olview you refer to.

Kind regards,

Jan Flikweert

 
Chris,

Chris Miller said:
And if it's an assembly DLL you'll never be able to load it with DECLAREs, no matter if 32bit or not.

The next link shows:
RUNDLL32.EXE <dllname>,<entrypoint> <optional arguments>

But it does not return something.

How to execute a dll file

Kind regards,

Jan Flikweert
 
You're not making it easy to understand what this is as you show something from DependencyWalker, BUILD code for a VFP project and ask about Visual Studio.

If this is a DLL from a VFP project, it's - as you say - a COM dll. And you use it via CREATEOBJECT(), you neither run it nor DECLARE functions/methods from it.

An assembly (.NET) is almost like that, it just doesn't register with regsrv32 but with regasm. To use it from VFP you'd need to make it COM visible, that's not a default for assemblies.

DLL isn't DLL, there are function libraries, COM DLLs and Assemblies. And VFP can only DECLARE functions like Windows API functions or use COM servers or ActiveX controls, but assemblies only when they are built with COM visibility or a COM wrapper is designed to use the assembly indirectly.

When this is a VFP project, then the build process you show unregisters the previous DLL version before building the new one. Well, since Vista you only get a build also register a DLL correctly, when you run VFP as Administrator. And on the other side a build does both unregister and register, there is no need to unregister a DLL before compiling, all that needs to be done is release all instances of objects based on that DLL before the file can be replaced by a new build.

Dependency Walker is not for Assemblies or COM Servers or ActiveX.

Chriss
 
Chris,

Libfluidsynth-3 is indeed no VFP com dll. The next example returns a messagebox with "0". This shoul

Code:
WshShell = CreateObject("WScript.Shell")
retval = WshShell.run("c:\windows\system32\RunDll32.exe .\binx86\libfluidsynth-3.dll new_fluid_synth") 
MESSAGEBOX(STR(retval))

And to check if things are alive changing new_fluid_synth to new_fluid_s returns an error message non existing function. This is correct.

Kind regards,

Jan Flikweert
 
Chris, Joe,

This is an idea I read from Olas Doschke (If I spell it correct). The strange thing is it loads a 64-bit dll. The retval is Type X.

Code:
PUBLIC WshShell AS Object
WshShell = CreateObject("WScript.Shell")
oExec = WshShell.exec("c:\windows\system32\rundll32.exe .\binx64\libfluidsynth-3.dll") 
oExec.StdIn.WriteLine("new_fluid_settings")
retval=oExec.StdIn.WriteLine("midi.winmm.device='MIDIPLUS61U'")
oExec.StdOut.ReadAll()
MESSAGEBOX(VARTYPE(retval))

Kind regards,

Jan Flikweert
 
Type "X" means NULL, there is no return value. Maybe that doesn't matter as what only matters is the effect this has. Just like a command has no return value but still an effect.
Does it work?

If not, do you have documentation of libfluidsynth? Or do you even have .NET source code for it as you were asking how to target 32bit cpus?

Wscript.Shell.exec does nothing much more than RUN. And you can RUN 64bit executables, no problem.
But you running DLLS (as in rundll32.exe) isn't the main way to use DLLs, they are, in any form, still libraries, class librafunction library, COM or not COM.

This documentation of RunDLL tells this can only run functions of a DLL made to be callable by RunDLL, so that's even less common to do, it isn't a more general method to run any function in any type of DLL, it's very specific, instead.

Besides that, the docs tell the syntax of command line options for Rundll.exe are the DLL to run and which function of the DLL to run, comma separated. There's not stdin necessary.

So all that code for your case could be done with
RUN /N rundll32.exe .\binx86\libfluidsynth-3dll,new_fluid_settings midi.winmm.device='MIDIPLUS61U'

Notice while VFP can run 64bit executables, access of C:\Windows\System32 (which is the system directory for 64bit system executables and DLLs) is redirected to instead access/run files from c:\Windows\SysWow64, so VFP could only run the 64bit version of rundll32.exe, when it would be copied out of System32 into some other directory not effected by the system directory redirection for the 32bit vs 64bit world.

If it's an assembly the usage is as said more like COM, you have methods of an object, not functions.

Chriss
 
Chris,

This posts needs clarification.

I am looking at a open source audio backend for the midi solution. FluidSynth is a very good solution. It should be possible to create a full virtual pipe organ in vfp using fluidsynt and no other software needed. Because Fluidsynth is open source this solution should be open source. And Fluidsynth is very popular in f.e. the jOrgan community.

Here a link to the user manual of Fluidsynth.

User manual Fluidsynth

Lucky there are more options to use this. Here after a part of the code which actually produces sound. It opens a shell and you can send
commands as can be seen Stdin.WriteLine.
I do not know if RUN /7 can send single commands to the shell.

Code:
PUBLIC oWSH AS Object,oExec AS OBJECT
oWSH = CreateObject("Wscript.Shell")
oExec = oWSH.Exec(".\bin\fluidsynth.exe -d wasapi  -m winmidi -g 1 -r 48000 interp 7 .\sf2\test.sf2 -o midi.winmidi.device='1:MIDIPLUS61U'")
oExec.StdIn.WriteLine("set synth.midi-channels[256]")
oExec.StdIn.WriteLine("set synth.midi-bank-select['gm']")
oExec.StdIn.WriteLine("set synth.reverb.active[0]")
oExec.StdIn.WriteLine("set synth.chorus.active[0]")
oExec.StdIn.WriteLine("set synth.cpu-cores[5]")
oExec.StdIn.WriteLine("set synth.polyphony[2048]")
oExec.StdIn.WriteLine("set synth.overflow.age[0.55]")
oExec.StdIn.WriteLine("set synth.overflow.percussion[0.1]")
oExec.StdIn.WriteLine("set synth.overflow.released[0.5]")
oExec.StdIn.WriteLine("set synth.overflow.sustained[0.1]")
oExec.StdIn.WriteLine("set synth.overflow.volume[0.4]")
oExec.StdIn.WriteLine("interp[7]")
oExec.StdIn.WriteLine("select 0 0 0 15")  
oExec.StdIn.WriteLine("select 1 0 0 1")  
oExec.StdIn.WriteLine("select 2 0 0 3")  
oExec.StdIn.WriteLine("select 3 0 1 1")  
oExec.StdIn.WriteLine("select 4 0 0 5")  
oExec.StdOut.ReadAll() && or Read() or ReadAll() or ReadLine()

For me it is interesting to look at the API. The WinShell solution does not need to process returning variables. You only send messages.

Even if we can manage to communicate with the libfluidsynth api i think it is C based and uses typedefs. So it not so easy to do it.

I have an example of a Java program which uses this API. I suppose Java is more compatible with C typedefs then VFP.

F.e. the API call new_fluid_settings returns a typedef which is used in other function calls. Forgive if I state it wrong and it are object references. I have the source code in Java for a full solution using the Fluidsynth API.

Java:
context->settings = new_fluid_settings();
fluid_settings_t* settings = new_fluid_settings();

Kind regards,

Jan Flikweert
 
Yes, it seem a c DLL using stdcall convention,

All the function declarations are in So you know which returrn type to declare, and what parameters.

There's no new_fluid_settings in there, though.

There are also build instructions. Perhaps best use the instructions for VS on Windows:

Or go Linux, it's easy to have a raspberry pi or just a VM with Linux.

Well, and what you try to use must be this:
And there you have the documentation of new_fluid_settings at It states: Create a new settings object.

But it only returns a pointer to a C object, it's not COM, nor can you do anything with the object, call its methods etc. unless you start programming that in C or other languages.
A VFP object also is mainly a pointer to an address in memory, but that's not making it the same thing. And since there seems no COM layer you can't have OLE objects that are usable within any COM capable programming language.

So you better make use of the command handler with all functions of it defined in the fluid_cmd.h header file (see above).

I can't dive in deeper into this right now.

Chriss
 
Hello,

sorry to jump in.
This is not my world, but some ideas come to my mind :

Accessing it with the .net wrapper and accessing that with wwdotnetbridge or kodnet.
I remember jack ryan giving samples of using c code within vfp code using vfpa
Maybe vfp2c32 may help on buiding structures in vfp


Best regards
tom
 
Helle Tom,

Thanks for your reply. Any help and thinking is appreciated.

The point is as far as I can see this problem is not an structure issue. But as you correctly state vfp2c32 helps with typedef structs, struct union structs and enumeration. The program vfp2c32front.exe can convert C structures, typedefs structs, enums to VFP code. And that is awesome.

tomk3 said:
sorry to jump in.

Kind regards,

Jan Flikweert
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top