QT project and USB connection - c++

I have problems with FTD2xx driver.
I'm using QT(C++) in Fedora 26 (64-bit) and the last version of FTD2xx for "2232H" device.
Also the build method is:
qmake /Address/ProjectName.pro -r -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug
Problem:
The FT_Status return 0(FT_OK) at ft_openex(....) command, but that return none_zero(FT_OK) for other functions of FTD2xx lib;
A section of my code:
FT_HANDLE ftH;
FT_STATUS ftStatus;
ftStatus = FT_OpenEx(const_cast<char*>("MYDevName"), FT_OPEN_BY_SERIAL_NUMBER, &ftH);
std::cout<<"FTST open:"<< ftStatus<<std::endl;
char a[10];DWORD b;
ftStatus = FT_SetBitMode(&ftH,0xff,0);
std::cout<<"FTST RESET:"<< ftStatus<<std::endl;
ftStatus = FT_SetBitMode(&ftH,0xff,0x40);
std::cout<<"FTST SPEED:"<< ftStatus<<std::endl;
ftStatus = FT_Close(&ftH);
std::cout<<"FTST CLOSE:"<< ftStatus<<std::endl;
And output :
FTST open:0
FTST RESET:1
FTST SPEED:1
FTST CLOSE:1
ftStatus =1 ;means FT_INVALID_HANDLE.
and
Command <<rmmod ftdi_sio >> is using.
and
Lib directory: /dev/local/lib
and
QT setting:
LIBS += -L$$PWD/../../../usr/local/lib/ -lftd2xx
INCLUDEPATH += $$PWD/../../../usr/local/include
DEPENDPATH += $$PWD/../../../usr/local/include

The FT_HANDLE is an output parameter in FT_OpenEx. You are correctly passing &ftH so that the function can overwrite ftH.
The FT_HANDLE is an input parameter to the other functions. You are incorrectly passing &ftH and should pass just ftH.
FT_Close(&ftH);
FT_Close(ftH);
Unfortunately FT_HANDLE is defined in a loosely-typed way:
typedef void* PVOID;
typedef PVOID FT_HANDLE;
Since void** implicitly converts to void*, the compiler cannot help you catch this mistake1. In general opaque handle types should be declared as
typedef struct AlwaysIncompleteType * MY_HANDLE;
and then the pointer and double-pointer types will be appropriately incompatible.
1 Even worse, in C, the reverse conversion from void* to void** is also implicit and you would be allowed to call FT_OpenEx(..., ftH) probably resulting in an immediate access violation (aka segmentation fault) and possibly resulting in unpredictable memory corruption. At least C++ got this right... but void* is still not conducive to strong type checking.

Related

Solaris' stdlib.h functions implemented by C++ libs?

I am struggling with a port of an open-source tool to Solaris. Most things work, cmake/pkg-config/etc. are there, dependencies are found, gmake works, compiler and linker calls look all fine and tren, boom:
Undefined first referenced
symbol in file
std::qsort(void*, unsigned int, unsigned int, int (*)(const void*, const void*)) ...
This part I don't understand. At the first glance, std::qsort does not make sense, it is supposed to be part of C library, not STL. So I looked into stdlib.h and found a list of things like using std::sort; and dozens of other standard functions like free, malloc, atoi, etc., redirected in case of C++ context.
What is Oracle doing there and why? Which library am I supposed to link with if they do redirect it like this? Or why does CC command not pull that in automatically like GCC does?
I tried adding -lstdc++ but no luck.
Alternatively, the plain libc versions seem to be defined in <iso/stdlib_c99.h> (or <iso/stdlib_iso.h>). Is it legal to include one of those headers directly or will this wreak other random havoc at link time?
Edit:
since there are multiple suspicions of the build system weirdness, here is the basically the linking call from the gmake execution:
/opt/developerstudio12.6/bin/CC -std=c++11 -xO3 -DNDEBUG <i.e. bunch of object files> -o ../systest -L/opt/csw/lib/64 -lintl
I cannot see anything special there and I expect CC to figure out what to link to get the obligatory functionality.
The rule is that #include <xxx.h> puts names into the global namespace and is allowed to also put them in std. Conversely, #include <cxxx> puts names into std and is allowed to also put them into the global namespace. In practice, this means that there are two approaches to implementing the functions from the standard C library in C++: declare the standard C library names in the <xxx.h> headers and hoist those declarations into std in the cxxx headers, or declare the names in std in the headers and hoist those declarations into the global namespace in the <xxx.h> headers. With the former approach, the name of the function will be qsort; with the latter, it will be std::qsort. Either way, that error message usually indicates a setup problem with the compiler. The linker isn’t finding the standard library.
This compile command
/opt/developerstudio12.6/bin/CC -std=c++11 -xO3 -DNDEBUG ...
will produce a 32-bit executable. Per the Oracle CC man page:
On Oracle Solaris, -m32 is the default. On Linux systems supporting 64-bit programs, -m64 -xarch=sse2 is the default.
But this library option
-L/opt/csw/lib/64
is searching a directory full of 64-bit libraries.
Either add -m64 to the compile command or use the 32-bit library path.
Update
The question almost certainly would be answerable had it included the full error message, which is almost certainly something like this:
CC -g qsort.cc -o qsort
"qsort.cc", line 15: Error: Could not find a match for std::qsort(int[4], unsigned, unsigned, int(void*,void*)) needed in main(int, char**).
"/usr/include/iso/stdlib_iso.h", line 184: Note: Candidate 'std::qsort(void*, unsigned, unsigned, extern "C" int(*)(const void*,const void*))' is not viable: argument '4' can't be converted from 'int(void*,void*)' to 'extern "C" int(*)(const void*,const void*)'.
"/usr/include/iso/stdlib_iso.h", line 187: Note: Candidate 'std::qsort(void*, unsigned, unsigned, int(*)(const void*,const void*))' is not viable: argument '4' can't be converted from 'int(void*,void*)' to 'int(*)(const void*,const void*)'.
This code works just fine when compiled with Oracle Developer Studio 12.6 on Solaris 11.4:
#include <stdlib.h>
int compare( const void *p1, const void *p2 )
{
int i1 = *( ( int * ) p1 );
int i2 = *( ( int * ) p2 );
return( i1 - i2 );
}
int main( int argc, char **argv )
{
int array[ 4 ] = { 5, 8, 12, 4 };
qsort( array, sizeof( array ) / sizeof( array[ 0 ] ),
sizeof( array[ 0 ] ), &compare );
}

Defining uint="unsigned int" is not being applied as I expected using nvcc in Visual Studio

Sorry, stuck with VS2013 but I don't think that is a problem. The same code compiles correctly on linux. I assume I need to define uint rather than edit 100+ lines of code.
I am getting "error : explicit type is missing ("int" assumed)" on first line of below code
__device__ uint inline get_smid(void)
{
uint ret;
asm("mov.u32 %0, %%smid ;" : "=r"(ret) );
return ret;
}
At the property for the app there is only CUDA => Host => Preprocessor Definitions I put in
WIN32;uint="unsigned int"
This seemed to fix the "assumed int" but now I am getting "error : expected a declaration"
Replacing uint with unsigned int in the source will compile without error. There is a lot of uint and this breaks with the linux build. Is more required besides 'uint="unsigned int"'? Maybe a switch to cause the NVCC to accept the uint and not give an error?
Just discovered a lot of ushort and I am guessing the same problem. Also, looking at the Linux build, the source were compiled with gcc but the link was done with nvcc so there is a difference.
====sample CUDA has ushort====
i must have not set up the include correctly as these variables are probably ok to use.
I gave up trying to define uint or ushort as the sample CUDA programs had
typedef unsigned int uint;
typedef unsigned short ushort;
so I just put those in each cu file that needed it.

Error in Parsing functions Calling Conventions using Libtooling ASTFrontendAction

I'm using Libtooling to parse Windows SDK headers but there is a problem in getting functions calling conventions, The libtooling always return __cdell for WINAPI or __stdcall calling convention which is the defualt calling convention of Win32 API's.
This is an input example
VOID
__stdcall
TestFunction (_In_ BOOLEAN is_valid);
This is my Function Visitor function of my RecursiveASTVisitor
virtual bool VisitFunctionDecl(clang::FunctionDecl *func)
{
// ...
if (m_AstContext->getSourceManager().isInMainFile(func->getLocation()))
{
if (func->hasAttrs())
{
auto stdcall = func->hasAttr<StdCallAttr>(); // always return False
}
const clang::FunctionProtoType * prototype = func->getType()->getAs<FunctionProtoType>();
if (prototype)
{
auto stdcall = prototype->hasAttr(attr::Kind::StdCall); // always return False
errs() << clang::FunctionType::getNameForCallConv(prototype->getCallConv()).str() << " "; // always return cdecl
}
func->dumpColor(); // But there is __attribute__((stdcall)) in dumped output!
}
// ...
}
And finally output of func->dumpColor(); for input example!
^
FunctionDecl 0x218c95bb6f0 <C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\winnt.h:430:14, C:\ExampleInput.h:18:36> col:1 TestFunction 'void (BOOLEAN) __attribute__((stdcall))':'void (BOOLEAN)'
`-ParmVarDecl 0x218c95bb5c0 <col:20, col:28> col:28 is_valid 'BOOLEAN':'unsigned char'
I ran it with/without this options too, for compatibility reasons but no difference at all :-(
-fms-compatibility
-fms-extensions
-fms-compatibility-version=19
Any idea?
Update
I found the problem, It's because of defualt compile config of #Clang. It's 64-bit (in 64-bit toolchain), And it doesn't work with __stdcall in 64-bit mode
If I use the 32-bit version (or -m32 option) then it will works correctly
Any idea why it happens in 64-bit mode?

Problems compiling C++ programs with wineg++/winelib

I am having trouble compiling C++ programs with wineg++. To illustrate my problem, I have written two test programs.
msgbox.cpp
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <windows.h>
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
char buf[30], *pos = buf;
int xs[] = {1,3,2,4,3,5,4,6,5,7,6,8,7,9};
std::sort( std::begin(xs), std::end(xs) );
for (int x : xs) {
pos += std::sprintf(pos, "%d ", x);
}
MessageBox(0, buf, "Hello", 0);
return 0;
}
frame.cpp
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
CWinApp winApp;
CFrame frame;
CWnd view;
frame.SetView(view);
frame.Create();
winApp.Run();
}
The second program uses the Win32++ library, which I can't recommend enough.
Both programs compile and run just fine using a cross-compiler:
okuu% x86_64-w64-mingw32-g++ msgbox.cpp -o msgbox.exe
okuu% wine ./msgbox.exe
okuu% x86_64-w64-mingw32-g++ frame.cpp -o frame.exe -lgdi32 -lcomctl32 -static
okuu% wine ./frame.exe
okuu% rm *exe*
But I want to use winelib so that I can use both the Windows API and Unix libraries. This is what I tried first:
okuu% wineg++ msgbox.cpp -o msgbox.exe
okuu% ./msgbox.exe
okuu% wineg++ frame.cpp -o frame.exe -mwindows
In file included from ../win32xx/include/wxx_appcore.h:57:0,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
../win32xx/include/wxx_appcore0.h:120:12: fatal error: process.h: No such file or directory
#include <process.h>
^~~~~~~~~~~
compilation terminated.
winegcc: g++ failed
Then I read wineg++'s man page, which says:
-mno-cygwin
Use Wine implementation of MSVCRT, instead of linking against the host system libc. This is necessary for the vast majority of Win32 applications, as they typically depend on various features of MSVCRT. This switch is also used by the MinGW compiler to link against MSVCRT on Windows, instead of linking against Cygwin libc. Sharing the syntax with MinGW makes it very easy to write Makefiles that work under Wine, MinGW+MSYS, or MinGW+Cygwin.
So I tried again with -mno-cygwin, and got a 2000-line error message that begins with:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cstdlib:75:0,
from /usr/include/c++/7.2.1/bits/stl_algo.h:59,
from /usr/include/c++/7.2.1/algorithm:62,
from ../win32xx/include/wxx_appcore0.h:110,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
/usr/include/stdlib.h:310:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *fptr; /* Front pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:311:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *rptr; /* Rear pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:312:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *state; /* Array of state values. */
^~~~~~~
wint_t
/usr/include/stdlib.h:316:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *end_ptr; /* Pointer behind state table. */
^~~~~~~
wint_t
/usr/include/stdlib.h:320:8: error: ‘int32_t’ has not been declared
int32_t *__restrict __result) __THROW __nonnull ((1, 2));
^~~~~~~
So it seems C99's fixed-size integer types are not available. That seems easy enough to solve:
frame.cpp
#include <stdint.h>
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
// etc. etc. etc.
And I tried again, but got a different 2000-line error message that begins with:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cwchar:44:0,
from /usr/include/c++/7.2.1/bits/postypes.h:40,
from /usr/include/c++/7.2.1/bits/char_traits.h:40,
from /usr/include/c++/7.2.1/string:40,
from ../win32xx/include/wxx_appcore0.h:111,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:2:
/usr/local/include/wine/msvcrt/wchar.h:398:23: error: conflicting declaration of C function ‘size_t mbstowcs(wchar_t*, const char*, size_t)’
size_t __cdecl mbstowcs(wchar_t*,const char*,size_t);
^~~~~~~~
At this point I have run out of ideas. This is what I have understood so far:
My system's libc and Wine's MSVCRT have conflicting definitions. (This was probably to be expected.)
My system's libc++ is hardwired to work with my system's libc.
Wine comes with a MSVCRT, but not with a C++ standard library implementation.
The logical course of action with the information I have so far would be to look for a C++ standard library implementation that's compatible with Wine's MSVCRT, but I don't know of one. Does anybody here know of one?
The only solution I can think of is to stick with the system libc and write your own process.h. This file should either #include the standard header files that have the functions Win32++ needs or provide its own implementations of those functions. If Win32++ won't compile without a particular function but your program does not actually depend on that function, the implementation of that function can simply return 0 or another fake value.
If the system libc has a header file that Win32++ asks for, but the file does not declare all of the functions that Win32++ expects, you'll have to write a header file such as win32xx-compat.h that defines those functions and #include it before any Win32++ header.

gcc not giving warning even with -Wall flag

I call the function timer_settimer with an argument of type timer_t* (a pointer) or timer_t and gcc compiles both versions. Doesn't give any error or nothing else.
void initialize_timer(timer_t * tid, int seconds)
...
timer_settime(*tid, 0, ts, NULL) == -1;
OR
timer_settime(tid, 0, ts, NULL) == -1;
No error no nothing. (the first version works correctly. the second bugs).
This is my Makefile:
all:
gcc -Wall -ggdb -lrt -pthread -o jenia_thread thread.c
How can I make gcc output all the warnings?
Thanks in advance.
The type timer_t is defined as void*. Specifically, on my system, I have:
typedef void * __timer_t;
...
typedef __timer_t timer_t;
(You have to go several levels deep in system include files to find this; I compiled a small program with gcc -E to see the preprocessed source with all the includes expanded.)
Your system most likely has something similar, particularly if you're using the GNU C library.
The first parameter of timer_settime is of type timer_t, or void* -- which means that an argument of any pointer-to-object or pointer-to-incomplete type will be implicitly converted to void* and not require a compile-time diagnostic.
It's an unfortunate choice, and one that doesn't seem to be imposed by POSIX. You'll just have to be careful to pass an argument of the right type without any help from the compiler.