Information:
LabVIEW: 2019
Version: 19.0.1 (32-bit)
Operating system: Windows 64-bit
Labview crashes completely after an indefinite time. I call three functions of the C-DLL. I loop through all the functions of the DLL over and over again. After about 2 minutes to an hour Labview crashes without reason.
Calling of OpenConnection():
Calling of QueryOpenConnectionStatus():
Calling of CloseConnection():
Type definition of TConnectionResult
Follow the given Headerfile.h
#ifndef __epMCOMLib_h_
#define __epMCOMLib_h_
#include <stdint.h>
#include <stddef.h>
#define DLLIMPORT __declspec(dllimport)
#pragma pack (push,1)
typedef struct {
uint16_t DLLFailureCode;
uint8_t ConnectionStatus;
uint32_t SystemFailureCode;
} TConnectionResult;
#pragma pack (pop)
#ifdef __cplusplus
extern "C" {
#endif
DLLIMPORT uint16_t __cdecl OpenConnection(uint8_t PortType,
char * PortName,
uint32_t OnConnectSucces,
uint32_t * Handle);
DLLIMPORT void __cdecl QueryOpenConnectionStatus(uint32_t Handle,
TConnectionResult * Result);
DLLIMPORT uint16_t __cdecl CloseConnection(uint32_t Handle);
#ifdef __cplusplus
} // extern "C"
#endif
#endif //#ifndef __epMCOMLib_h_
The DLL works perfectly. For this I integrated the DLL in Python ,LabWindows/CVI, C++ and Delphi. There is no crash in these programming languages!
Can anyone give me any useful tips on how to further isolate or eliminate the error.
Even if a function of the DLL has been executed and the DLL is then closed, it still causes a crash. As if it's still in memory. It feels like looking for a needle in a haystack.
Run the thread on the UI thread instead of any thread!
In the log file of the DLL I could see that the thread is attached and detached. I suspect this is causing a memory violation. Since Labview is shot down by its called DLL.
In my experience, sometimes DLL called with LabVIEW causes this kind of problems and with no specific reasons and solutions (even for the NI technical support).
Try to launch your LabVIEW applicatin with Administrator privilegies. In some cases, this solves the problem.
Related
I built a multi-language software image processing program and made it generally available with binaries for Mac OS X and Ubuntu. The binaries have been tested on their respective operating systems and every thing works perfectly. I recently also tried to release binaries for Windows (64 bit) but the GCC (through MinGW-w64) compiler gave me warnings for one of the C programs when I create the shared library (dll) file. This did not happen in Mac OS X or Ubuntu. Here are the warnings and the corresponding line of code in the C file:
warning: passing argument 3 of '_beginthreadex' from incompatible pointer type [enabled by default]
Line 464:
ThreadList[i] = (HANDLE)_beginthreadex( NULL, 0, &ThreadFunc, &ThreadArgs[i] , 0, NULL );
The second and stranger warning:
c:\mingw\x86_64-w64-mingw32\include\process.h:31:29: note:
expected 'unsigned int <*><void *>' but argument is of type 'void * <*><void *>'
_CRTIMP uintptr_t _cdecl _beginthreadex<void *_Security,unsigned _Stacksize,unsigned <_stdcall *_StartAddress> <void *>,void *_ArgList,unsigned _InitFlag,unsigned *_ThrdAddr >;
Line 34:
#include <process.h>
This belongs in this larger code block:
/* Multithreading stuff*/
#ifdef _WIN32
#include <windows.h>
#include <process.h>
#else
#include <pthread.h>
#endif
#include <stdbool.h>
The problem seems to emanate from #include <process.h> since for Mac OS X and Ubuntu #include <pthread.h> is used. Any help figuring this out? The full C program is here .
The messages when compiling for windows but not for other systems are hardly surprising. The offending code will only be seen by the compiler when building for windows, due to usage of the _WIN32 macro which is only defined by the compiler when code is built for windows.
The "second and stranger warning" is describing the cause. The third argument of the (windows specific) _beginthreadex() function is specified to be a pointer to a function that returns an unsigned int. The actual ThreadFunc being passed is a function that returns a void *.
The fix to make the code acceptable to a windows compiler is to change the return type of ThreadFunc() to return unsigned int. That will break the code for other systems, so you need to do the changes conditionally (i.e. have two versions of the function, and select the right one by testing the _WIN32 macro).
#ifdef _WIN32
/* use the windows version of the function here */
#else
/* use the non-windows version of the function here */
#endif
I'm trying to call a C style library called "universal speech" from AutoIt 3 (latest version). I get the desired action from the function I'm calling but after I get the response AutoIt crashes saying "AutoIt has stopped working, Windows can search for the solution..." Am I doing something wrong?
AutoIt:
#notrayicon
dllcall("UniversalSpeech.dll", "int", "speechSayA", "str", "test 123", "int", 1)
sleep(1000)
universal speech.h:
#ifndef ____UNIVERSAL_SPEECH_H__
#define ____UNIVERSAL_SPEECH_H__
#if defined __WIN32 || defined __WIN64
#define export __declspec(dllexport)
#else
#error Platform currently unsupported
#endif
#ifdef __cplusplus
extern "C" {
#endif
int export speechSayA (const char* str, int interrupt) ;
#ifdef __cplusplus
} // extern "C"
#endif
#endif
I successfully did this in other programming languages but AutoIt doesn't seem to like it.
"binhnx" on AutoIt forum solved my problem:
This library uses the cdecl calling convention and AutoIt by default uses the stdcall calling convention. Cdecl is supported, though you have to tell AutoIt that you want to use it by entering :cdecl next to the return type of the function you're calling.
So in my case instead of:
dllcall("UniversalSpeech.dll", "int"...)
you'd go like this:
dllcall("UniversalSpeech.dll", "int:cdecl"...)
Which solves the crash.
I'm writing a function that should have two versions: a debug version and non-debug version. Which one of the two functions is used should be decided by the caller.
I want something like this:
caller.c
// comment out the following line when not necessary anymore
#define MY_FUNC_DEBUG
#include "my_func.h"
// some code that calls my_func()
my_func.h
void my_func(void);
my_func.c
void my_func()
{
// lots of code
#ifdef MY_FUNC_DEBUG
// debug code
#endif
// more code
}
This obviously won't work, because my_func.c is compiled separately from caller.c, therefore it can't know what macros it defined.
How can I make this work easily? I wouldn't want to write the two versions of my_func separately, because they share most of their code.
Assuming that you are using gcc, this problem can be easily solved by defining the macro at compile time via the -D option in both files.
In your example you could compile both files using -D MY_FUNC_DEBUG when you want the debug code to be activated and nothing otherwise. There is not need for defining MY_FUNC_DEBUG in caller.c.
Make the debugging code in my_func() switchable at run-time.
my_func.h
#ifndef MY_FUNC_H_INCLUDED
#define MY_FUNC_H_INCLUDED
extern int my_func_debug(int level);
extern void my_func(void);
#endif
my_func.c
#include "my_func.h"
static int debug = 0;
int my_func_debug(int level)
{
int rv = debug;
debug = level;
return rv;
}
void my_func(void)
{
...
#ifdef MY_FUNC_DEBUG
if (debug)
...debug...
#endif
...
}
caller.c
void consumer(void)
{
int old = my_func_debug(9);
my_func();
my_func_debug(old);
}
Discussion
The outline code means that you can have one copy of the source for my_func.c, but it can be compiled with debug included, or with it excluded. The consumer code (caller.c) can request the level of debugging it wants, but whether that does anything useful depends on whether the copy of my_func.o (my_func.obj on Windows) was compiled with debug included. You get one source file; you get to choose which variant of the object file is included in the program with caller.o. And at runtime you can request debugging.
Note that my_func_debug() is unconditionally defined; it just doesn't do anything very useful if the my_func.c code is not compiled with -DMY_FUNC_DEBUG.
In object-oriented languages (C++) you can execute code before main() by using a global object or a class static object and have their constructors run the code you want.
Is there any way to do this in C? I don't have any specific problem I'm trying to solve, I'm just curious. One thing this might be useful for is automatically initializing a library.
You can do it with __attribute__ ((constructor)). I've tested the following example with both gcc and clang. That being said, it's not part of the language.
#include <stdio.h>
void __attribute__ ((constructor)) premain()
{
printf("premain()\n");
}
int main(int argc, char *argv[])
{
printf("main()\n");
return 0;
}
It does the following:
$ ./test
premain()
main()
GCC documents it at: https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes
There are ways using __attribute__ but those are very specific to your compiler and code that is written using these are not really portable. On the other hand, the C language does not provide any start-up modules/libraries.
In C, logically main() is the first function called by the OS. But before calling main(), the OS calls another function called start-up module to setup various environment variables, initialize (un-initialized) static variables, build a stack frame (activation record) and initialize the stack pointer to the start of the stack area and other tasks that have to be done before calling main().
Say if you are writing code for embedded systems where there is no-or-minimal OS to do the above mentioned work, then you should explore these options which are compiler dependent. Other than GCC, Turbo-C and Microsoft C compilers provides facilities to add code in a particular hardware machine (f.e. 8086 machines).
In other words, the start-up modules are not meant for the programmers.
With gcc, you can do so by using the constructor function attribute, e.g.
__attribute__ ((__constructor__))
void foo(void) {
...
}
This will invoke foo before main.
Note: This is probably not portable to other compilers.
You can initialize global variables but not call functions within these initializations.
If your compiler can compile cpp files you can add a file with a class that call in the costructor your initialization code. The class must be allocated statically. For example:
#include "ext.h"
class cext
{
public:
cext()
{
ExtInit();
}
~cext(){};
};
cext g_cext;
The ExtInit() function must be defined as extern "C" in file ext.h.
#ifdef __cplusplus
extern "C" {
#endif
void ExtInit (void);
#ifdef __cplusplus
}
#endif
I have following function defined in one dll:
__declspec( dllexport ) int __stdcall
mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile )
I need to write one process to call the above function.
I am doing it first time,I do not have much idea.
I have written the following code
#include <windows.h>
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <limits.h>
extern __declspec( dllexport ) int __stdcall mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile );
typedef INT (*MJSCALL) (char *,DWORD, char *, char *);
int main()
{
char *a,*b,*c;
a=NULL;
b=NULL;
c=NULL;
DWORD aa =1;
int i;
HMODULE hLib;
MJSCALL ADD;
hLib=LoadLibrary("f3cucall.dll");
if(hLib==NULL)
{
return 1;
}
ADD=(MJSCALL)GetProcAddress(hLib,"mjscall");
if (ADD==NULL)
{
return 1;
}
(ADD)(a,aa,b,c);
return 0;
}
The "(ADD)(a,aa,b,c);" is causing the problem.
Can somebody help me out?
I think you mixed two things up:
the __declspec(dllexport) MSVC keyword exports functions from a DLL (tells the linker to do so), and the __declspec(dllimport) imports functions from a DLL. This is done at loading time, the linker will create all the necessary code to load the DLL and resolve the symbol. In fact, it adds some code to the exe to let the OS load the DLL. You can use functions declared with __declspec(dllimport) just like any normal internal function.
If you want to use this approach, you need the DLL's lib file, since it contains information for the linker to resolve the symbolic name. It doesn't actually contain code, only these information on the DLL for the linker. Additionally, you have to tell the linker that the function you want to use is located at a DLL, using the magic __declspec(dllimport) before the function declaration. That's why you provide a .lib and a header file (containing these declarations) with your DLL if you want to do it this way. You should rebuild the project that uses the DLL when you change the DLL, as the .lib file may have changed.
You can use the same header file in your DLL project and the projects that import from this DLL:
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
MYDLL_API void printMe(int);
The MyDLL_API get resolved to either __declspec(dllexport) (in the DLL project, where you define the MYDLL_EXPORTS in the project settings) or __declspec(dllimport) (in all projects that use the dll). This way, you only need one header file for the DLL.
Another method of calling DLL functions is to use LoadLibrary and GetProcAdress. These two are used to load a DLL at runtime. The main difference between loading a DLL at loading time and at runtime is that you have some control over loading the DLL at runtime, whereas the OS will do the job when the DLL is to load at loading time (e.g. show a message box if the DLL cannot be found and do not run the process).