Jump to content

PostgreSQL dll issue

Recommended Posts

Thanks to the nice work of drjdpowell I was able to easily connect & work with PostgreSQL. Did have to use the 32bit included dll's though.

Now when I try to install & run it on a Win10 IoT machine the dll's are not found and throwing errors. Sorry no screenshot at the moment.

The 64bit of PostgreSQL is installed on both machines & works.

The exe of course works just fine on the dev machine.

Does anyone have any ideas? I'm at a loss at the moment & need to get this running.


Link to comment

If this is an EXE, see if libpq.dll and other dlls are included with the EXE, in its "data" folder.  This should happen automatically (because the dlls are part of the PQ class), but I've seen this fail before.  If they aren't there try using "Always Include" to include them.  The data folder should look like this:


Link to comment

Correct, the above is exactly the same for the build & works from different directories on the dev machine. It's on the deployed machine it gives errors.

In the Build properties for the exe I've tried to set the destination to a specific path but it didn't help. Perhaps I missed something?


Link to comment

On a regular Win10 box the exe loads the dll's just fine & then times out as expected without Postgresql installed. So it's looking a lot like a Win IoT issue...

My understanding is that you wrapped 32 bit dll's with a CIN.

Looking at does-windows-iot-support-my-dll

the answer was:

Windows IoT required DLL to be as follows:

  • Compiled using the ARM target
  • Needs to target .NET Core

Those restrictions strictly apply when using UWA you may be able to get away by using a console app but it is not that simple on IoT as everything is sandboxed.

Otherwise the other way to use the DLL on the Pi is to run a nix OS like Raspbian, install the latest MONO and then you can embed DLL's into your projects and it should just run, even if targeted for x86 - Thanks to all the clever stuff mono does.

Edited by FixedWire
Link to comment

If Postgres is already running on the Win 10 IoT box, I should be able to link the CINs to the same installation C:\Program Files\PostgreSQL\11\bin. Theoretically.

LabVIEW 64bit hung up when linked to these installed dll's. Hence using the 32 bit dll's supplied & going that route in the first place. It just worked. Note that there also some changes such as libint.dll likely replaced by the libintl-9.dll in the \11\bin directory.

Win 10 IoT Enterprise should be able to run regular programs where as the Core version is limited to UWP apps (understanding this requires ARM compiled code). what-s-difference-between-windows-10-iot-versions

I think Win IoT is mulching things somehow where regular Win 10 accepts the dll's.

Looks like the best approach for right now is to remotely get into the database via the localhost/IP address and run things on a laptop. Your help's been very appreciated!

Link to comment

Windows IoT is not a normal Windows installation at all, except the Windows IoT Enterprise version. The others are really just embededded kernels without any real Win32 subsystem. Accordingly many standard Windows DLLs like kernel32.dll, user32.dll and many more are not present there. It is basically a Windows installation with a much smaller embedded kernel that only supports Universal apps from the app store.

Accordingly a normal LabVIEW build application that you created on your dev machine should NOT even be able to be started as they are build for x86 and not ARM and require a fully functioning Win32 subsystem. How do you target your IoT system?

Link to comment

Yes, correct Rolf. The target was the enterprise version & that's why it ran in the first place.

Interestingly enough installing the exe on 3 other machines under Win10 resulted in the 2 working & the 3rd not finding the dll just like the Win10 IoT. With a new build it suddenly didn't find the dll on one that did work. With not having time to debug I created an installation and the program worked since even with new builds. On regular Win10 there shouldn't have been an issue...
At this point I'll try and link the latest 64bit Postgres dll's & try that.

Link to comment

Well in that case the remark about the DLLs having to be compiled for ARM was really off. That is for Windows IoT installations on targets like the RPi and similar boards which all have an ARM CPU (and accordingly can't run Windows IoT Enterprise either which is a pure x86/x64 install).

It all depends on which C compiler they used to create those DLLs. Until Visual C 2015 or so each Visual C version come with it's own specific C runtime library that had to be installed on every target on which you wanted to run an executable or DLL created with it. While many parts of Windows are compiled with Visual C too and therefore cause the Windows installation to come with the needed C runtime support already installed this can and will vary depending on the Windows version and the amount of extra tools and utilities that you install. Also any extra custom application you install such as LabVIEW also comes of course with the necessary C runtime support that gets installed if not already present on the system, but depending on all this a particular C runtime version may or may not be present on any particular system.

Basically you should never copy DLLs to a target system but install them with the proper installer for them which hopefully takes care about installing the correct C runtime support too.

Link to comment

Since there's still an issue with 32 working (but not on some machines) & the 64 bit hanging when trying to relink the dll to the installed PQ libraries, I tried to create the CIN wrappers automagically. The process gets stuck and becomes beyond my current knowledge. Don't know how you did it but kudos to you Mr. Powell! I'm sure you wrestled with this a bit. 😬


Looks like multiple .h files need to be referenced. libpq.dll needs the libpq-fe.h which in turn needs the stdio.h, postgres_ext.h & pg_config_ext.h according to: https://doxygen.postgresql.org/libpq-fe_8h.html

Just selecting a few basic options like open/close was not successful & returned: "The library specified for this node cannot be found or cannot be loaded."

Do you remember how you did it?



Link to comment

This has nothing to do with a CIN whatsover. CINs were a legacy technology in LabVIEW 3 and 4 before LabVIEW learned to interface to shared libraries (*.dll on Windows and *.so on Unix). What you are doing is not a wrapper either in the sense as it is usually used by me and others who are regularly dealing with this. A wrapper is another shared library written in C/C++ that interfaces to a certain API and translates it into a more LabVIEW friendly shared library interface that can be more easily interfaced with the Call Library Node.

You are trying to create a VI interface library to your shared library. And that is always a tricky business. For one the Call Library Node can't interface to every C feature out there. C++ object interfaces, callback pointers and also complex structures with embedded pointers are all things that can't be done with the Call Library Node (or in the case of complex structures with embedded pointers only with a lot of pain and by handcoding in LabVIEW what a C compiler would normally do mostly automatically).

The import library wizard you are trying to use for this is an amazing piece of software but despite its name NOT a magician. And extracting all the necessary information from a header to safely interface LabVIEW to a C shared library would be a truely magical feat, since the C syntax does not cover all the necessary details about buffer management and such things. This is only documented (if you are lucky) in the prosa library documentation that comes with your shared library. If you are unlucky you have to figure it out by guessing from naming conventions of variable names and lots of trial and error (meaning: crashing, restarting, editing, saving, crashing, goto begin). This is true for using a shared library in C just as much as in any other language including LabVIEW.

So even if the import library wizard can import all your functions you really have to go through each generated VI and manually check that the generated code is actually correct. Also the generated code is in an attempt to be rather safe than sorry often unneccessarily inefficiently programmed, which is another thing you should be changing. Of course this all requires that you know exactly how the shared library should be interfaced and if you really do that you end up very quickly with the constation that creating all those interface VIs from scratch by hand is not only about as fast as going through the import library wizard and then painstakingly check each of the VIs by hand, but also creates more efficient interface VIs with something more meaningful than the ugly standard light blue import library wizard icons and totally unpractical connector panes.

The import library wizard for instance can't know that in a function like:

int32_t MyAwesomeBufferReader(int32_t *buf, int32_t bufSize, int32_t *bufRead)

the second parameter is the size of the passed in buffer and the third is the size of how many data was actually filled in the buffer. It doesn't even know that the first is not just a pointer to a single int value but rather a pointer to an array. The C syntax does not distinguish between a pointer to a scalar and a pointer to an array, except that it allows to usually write 

int32_t MyAwesomeBufferReader(int32_t buf[], int32_t bufSize, int32_t *bufRead)

to show that the first parameter is actually an array, but this is not used by many programmers despite its increased readability (probably because some ancient C compilers didn't know about this syntax with an incomplete array size and some libraries are still written to compile even on computers that you can only see in musea anymore).

The first variant will likely default to a VI with an int32 value "bufSize" as input and two int32 value "buf" and "bufRead" as output and if you select the option to treat return values as error it will enter the return value into the error cluster as an error if it is not 0. It will also corrupt memory (and likely crash at some point) whenever being called with a bufSize value greater than 1!

The proper VI (just going from the somewhat arbitrary naming of the parameters) has however an int32 "number of samples to read" as input that says how much data should be read, and an int32 array output. Before calling the shared library function the interface VI should allocate an array of "number of samples to read" in length and on return of the function should use the "bufRead" value to resize the array to the actually returned data and then pass it back through the array output of the connector pane . The interface VI should hide all the buffer management details from any caller of the VI as otherwise you are going to expect every user of your VI to know not only about C programming details in general but about the actual programming interface of your shared library function. A totally unusable LabVIEW VI as such!

No automatic wizard in the world could be thought this in any way, and even what I just wrote is usually only a reasonable guess based on the parameter naming, which in C has absolutely no meaning in any way. (The actual parameter names can be left away completely in the function prototype without any adverse effect when using the function, and the names in the function prototype can be also completely different to the names in the actual function declaration, if the programmer wants to do that to obfuscate his code even more.) The actual library documentation would hopefully explain in detail what each parameter is meant to mean but you can't point an automated tool at a PDF or HTML file and tell it to extract any exact programming information from the prosa text in there. 

Edited by Rolf Kalbermatter
Link to comment
  • 1 year later...

we are experiencing a similar issue. We are using PostgreSQL On dev computers, with Windows 10 Pro, I create an exe with the example PQ Example Many INSERTS provided by drjdpowell. We only modify ipaddress, username and password. Everything works fine.

If I move the build folder (with the data folder) in a Win 10 Education, the exe cannot find the dlls. The attached image explains it all. Basically we get "Missing External function libpq.dll" even if the dll is in the data folder. This computer has NI run-time engine 2019 x86.

Interestingly, if I put the same folder on another Windows 10 Education, where I have installed LV, VIPM and the PostgreSQL vip, the exe runs well. This computer has also NI run-time engine 2019 x86 (and others).

Comparing the 2 Win 10 Education computers, It seems to me they both have the same Microsoft Visual C++ 2015-2019 Redistributable (x64) and Microsoft Visual C++ 2015 Redistributable (x86). I checked this aftert having read rolfk suggestion here 

What could the issue be? We are running out of things to attempt. Thanks for your support!


Edited by MzazM
Link to comment

Only suggestions I have are:

  1. Is the exe in that "builds" folder.  The EXE xpects teh dll at "<EXE's folder>/data".   Your screenshot shows the dll at "builds/data".
  2. Could be a missing dll that libpq.dll calls.  Try downloading a full set of Postgres dlls and place them in the data folder.
Link to comment

Thanks for your answer.

1. The exe is at the correct path

2. I downloaded the latest dll that i found on your repo in bitbucket: https://bitbucket.org/drjdpowell/pq-labview/src/master/Connection/ . No difference.

Important to notice that the same folder containing the exe (in the following screenshot I renamed the folder buildWin10Pro) works immediately in another Win10Education. The difference is that in this second system there is the whole LabVIEW, VI package manager and the Postgresql package installed.
Any follow up on this? Thanks!


Link to comment

We finally understood.
We saw that a full LV2019SP1 f3 installation solved the problem. I then noted that Run-time Engine 2015 SP1f13 comes with it. I remembered that drjdpowell mentioned here that he is using LV 2015.
So I removed the whole LV (double-checked that exe couldn't find dlls anymore), installed only the Run-time Engine 2015 SP1f13 and it worked immediately.

Don't know why but it is not automatically installed with the installer.

Edited by MzazM
Link to comment
16 minutes ago, drjdpowell said:

That doesn't make much sense.  Those DLLs aren't created by me; they are the standard PostgreSQL DLLs that I downloaded.  They can't have any dependencies on any LabVIEW stuff.

Yes, I agree with you. Indeed installing LabVIEW was the last thing I tried after almost 1week of more reasonable attempts (moving dlls, getting dll elsewhere and so on).

When I removed LV the exe was complaining about missing external function. Installed runtime engine 2015 and it worked. I do not know why. I could check tomorrow on another system where I have the same exe running for a long time, if I also have the runtime 2015 installed.


Link to comment
4 hours ago, drjdpowell said:

That doesn't make much sense.  Those DLLs aren't created by me; they are the standard PostgreSQL DLLs that I downloaded.  They can't have any dependencies on any LabVIEW stuff.

It could make sense if the PostgreSQL DLLs were compiled with Microsoft Studio 2010 or 2012 or similar (not sure which Visual Studio version is used for compilation of LabVIEW 2015) and set to use dynamic linked MS C Runtime library. It is old enough to not be standard on a recent Windows 10 installation and not new enough to not be tightly coupled with a specific Microsoft Visual C runtime version. Since about Microsoft Studio 2015, the Visual C runtime has stayed at version 14.x and doesnt with each new version require a new runtime. It's still possible that a newer Visual Studio application won't work with an older runtime but the opposite works usually without a glitch.

  • Thanks 2
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

By using this site, you agree to our Terms of Use.