0

I am attempting to implement some TWAIN functionality into a QT project. I have opened this code from the provider and compiled it. However when I past the code into my project it wont compile.

Basically I have 3 files CommonTWAIN.h, TwainAPP.cpp, and DSMInterface.cpp.

In CommonTwain.h I define a constant I believe, called. kTWAIN_DSM_DLL_NAME

/* CommonTWAIN.h */
#ifdef TWH_CMP_MSC
  #ifdef TWH_64BIT
    #define kTWAIN_DSM_DLL_NAME "TWAINDSM.dll"
  #else
    #define kTWAIN_DSM_DLL_NAME "TWAINDSM.dll"
  #endif // #ifdef TWH_64BIT
#elif defined(TWH_CMP_GNU)
  #define kTWAIN_DSM_DLL_NAME "libtwaindsm.so"
#else
  #error Sorry, we don't recognize this system...
#endif

In TwainApp.cpp I use that constant in a function call.

/*   TwainApp.cpp   */
LoadDSMLib(kTWAIN_DSM_DIR kTWAIN_DSM_DLL_NAME)

That function calls code that is in DSMInterface.cpp defined by

/*   DSMInterface.h   */
bool LoadDSMLib(char* _pszLibName);

I get stuck with this error

error

However The code also provides a visual studio solution that I can open and compile. This works as expected with the same code. So I am assuming I just have something configured wrong. This is fairly out of what I am comfortable with but I do think I am missing something simple.

So far I have tried adding QMAKE_CXXFLAGS += -permissive to the project file. no luck.

caleb baker
  • 144
  • 7
  • Also if there is anything I can do to clarify then please let me know. Always trying to improve how I ask the question. – caleb baker Aug 01 '22 at 18:54
  • 1
    in C++ string literals are `const` and for whatever reason the function `LoadDSMLib{}` takes non-`const`. – Persixty Aug 01 '22 at 18:56
  • 1
    `strdup()` might be of help – lorro Aug 01 '22 at 18:58
  • @Persixty so why then can the project compile until I try to copy the code over? – caleb baker Aug 01 '22 at 19:03
  • The project I'm trying to incorporate is https://github.com/twain/twain-samples/tree/master/TWAIN-Samples/Twain_App_sample01 – caleb baker Aug 01 '22 at 19:05
  • You could easily create a non-const char array `char LibName[] = kTWAIN_DSM_DIR kTWAIN_DSM_DLL_NAME;`, and then pass that as the parameter. – BoP Aug 01 '22 at 19:06
  • 1
    In the c++11 ( 2011) standard the compiler became more strict about this. Related: [https://stackoverflow.com/questions/61601872/why-do-string-literals-char-in-c-have-to-be-constants](https://stackoverflow.com/questions/61601872/why-do-string-literals-char-in-c-have-to-be-constants) – drescherjm Aug 01 '22 at 19:06
  • @Bop I did such with lorro's suggestion with the strdup() But I really want to understand why this happens. and I think dresherjm answered the question. by saying the compilers may be set different to allow this. – caleb baker Aug 01 '22 at 19:14
  • 1
    @calebbaker I'm guessing some compatibility setting in the project. What is clear is in C++ you shouldn't be able to pass a literal to that function because the parameter is not declared `const`. See this question: https://stackoverflow.com/questions/66771695/how-to-enable-non-const-string-literals-in-visual-studio – Persixty Aug 01 '22 at 19:14
  • 3
    @calebbaker -- The TWAIN samples are notoriously old, and have not been updated (many of them) in years. The rules of C++ has changed over the course of those years, and modern C++ (C++14, C++17, etc.) compilers may have an issue with those old samples. – PaulMcKenzie Aug 01 '22 at 19:15
  • 2
    Unless you're fond of memory leaks, `strdup` is only half a solution. You still need to free all those dynamic duplicates you'd be creating. You'd probably be better off just declaring anonymous name arrays of statics (ex: `static char kTWAIN_DSM_DLL_NAME[] = "TWAINDSM.dll";`). It's not pretty (puts a copy of the string(s) in each source file consuming the header), but it works, and alleviates your poor memory manager of heartache. – WhozCraig Aug 01 '22 at 19:30
  • @caleb - You seem to have two options here. Either add a compiler option or a cast to tell the compiler "I know this is wrong, but do it anyway", or you can add one (1) line of code that creates the non-const string required. Your choice! – BoP Aug 02 '22 at 07:49

2 Answers2

1

I don't like that cast much. I'm sure it will work fine in practise (well, almost sure) but I don't like it on principle.

Instead, I would do something like this:

std::string libname = kTWAIN_DSM_DIR kTWAIN_DSM_DLL_NAME;
LoadDSMLib(libname.data());

If you ❤️ QString then you can probably use that instead.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
0

you should be able to cast it away:

LoadDSMLib((char*)(kTWAIN_DSM_DIR kTWAIN_DSM_DLL_NAME))

as long as the function isn't trying to modify the string it should be fine.

  • At least use `reinterpret_cast` so it stands out. – Martin York Aug 02 '22 at 00:21
  • A C-style cast is a "Shut up and do it!" command to the compiler. And it *will* do it, whether it works or not. Also, I believe *"it should be fine"* are among those Famous Last Words., right next to "Don't worry, it is not loaded" :-) – BoP Aug 02 '22 at 07:55