|
Hello friends,
I am not able to understand this,could you help me.I am using Qt creature
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
void S7API CliCompletion(void *usrPtr, int opCode, int opResult);
~MainWindow();
.
.
.
void MainWindow::CliCompletion(void *usrPtr, int opCode, int opResult)
{
}
|
|
|
|
|
Such is often used to define a build specific calling convention (Calling convention - Wikipedia[^]).
In your case it seems to be defined in snap7.h[^]:
#ifdef OS_WINDOWS
# define S7API __stdcall
#else
# define S7API
#endif
I don't know how it got there. It is not Qt related and the QtCreator is probably ignoring it. It looks like you have copied the function definition from somewhere into your header file.
|
|
|
|
|
I added .h .c and .lib in my project so,so that it is defined in qt
|
|
|
|
|
Then there is no need to re-define and re-implement the function when already located in a library or an additional source file which has been added to the project.
However, I think pointing to calling conventions should have answered your question.
|
|
|
|
|
The function that I indicate above is related the example that it is client .I did just copy past properly.I wrote about calling convention and it say me ,you have to use macro with in .h and .c (prototype and function).Now, Qt didnt add the macro with function .I suppose I have to add .Am I right
|
|
|
|
|
Don't add the macro to a Qt class function.
You have two choices:
- Use the existing header and source files from the examples and add them to your project. Then call the function using the name and include the header file in the source files where you call it.
- Convert the examples by implementing all the code in Qt classes (source and header).
I would go for the first option. Than there is no need to implement a similar function as Qt class member. You might do so, but then the Qt function must not use the macro:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void CliCompletion(void *usrPtr, int opCode, int opResult);
};
#include "snap7.h"
#include "MainWindow.h"
void MainWindow::CliCompletion(void *usrPtr, int opCode, int opResult)
{
::CliCompletion(usrPtr, opCode, opResult);
}
|
|
|
|
|
So,You mean ,I must not use the macro because of the reason that you say.I added in my project .lib,.h,.c and Qt is handling this instead of me.I understand like this,I am new communication engineer this is why I dont know perfect C++.
By the way I create a new function Clicompletion is the function that I create,I will use it any where.
Maybe I got it wrong you.
|
|
|
|
|
You must not use the macro with Qt classes (and should not use it with C++ classes).
If you have another source file (or library) where the function is implemented, there is no need to implement it again as MainWindow class member.
It is even not necessary to use the macro when the function is part of a C++ source file in your project. It is only necessary when using a C library. Then the header file tells the compiler that the function in the library uses that calling convention and that it must create corresponding code when creating the assembly code for the function call.
C and C++ might use different calling conventions (depends also on the used compiler). Therefore, a compiler must know the calling convention when a C function is called from C++ code.
|
|
|
|
|
#ifdef OS_WINDOWS
# define S7API __stdcall
#else
# define S7API
#endif
Because of I use windows C++,I dont have to this with my functions,right?
|
|
|
|
|
It depends. See also my above post.
Such constructs are not necessary for C++. But they are required when calling C functions from C++ code depending on how the C code has been build. If the C code is part of your project and you set the project options to compile C code as C++ (that is: use the C++ compiler also for C code), there is no need for the macro. But if the C code has been compiled as C for Windows, it must be used.
|
|
|
|
|
As a result of these informations, as far as I understand,I can call the functions just with name that intellisense show me functions,so that no problem with snap7 and I can create functions as I always do.This would be strange with macro.
|
|
|
|
|
This is not a C language issue, it is something to do with Qt. S7API is a define variable that will be in one of the Qt header files, and perhaps also in the documentation.
|
|
|
|
|
|
This is my logic to find the longest word in C.
void find_long(char *a)
{
int l,i,l1=0,j=0,l2=0;
char b[50],c[50];
l=strlen(a);
for(i=0;i<l;i++){
if(a[i]!=" " ){
="" b[j]="a[i];
" printf("%c="" ",b[j]);
="" j++;}
="" else="" if(a[i]="='" '){
="" ;
="" if(strlen(b)="">l1){
strcpy(c,b);
l1=strlen(b);
j=0;
}
else{
printf("\nEOF");}
}
}
printf("\nlongest is \n");
printf(c);
But it is not taking the last word I am giving. What is wrong here?
|
|
|
|
|
You only check the length of each word when you encounter a space character. So if the last character is not a space then when the loop ends you still have an unchecked word in array b. Your code would be clearer if you formatted it properly and used <pre> tags round it. And also used meaningful names for your variables rather than single letters.
|
|
|
|
|
what condition I can add here to avoid it?
|
|
|
|
|
At the end of the loop you just need to check the last word in array b.
|
|
|
|
|
|
It is essential to "see" the code properly indented and formatted. Then you can recognise - besides the problems mentioned by Richard - that there is a missing closing parentheses (which should also issue a compiler error if not present behind the posted code):
void find_long(char *a)
{
int l,i,l1=0,j=0,l2=0;
char b[50],c[50];
l=strlen(a);
for (i = 0; i < l; i++) {
if (a[i] != ' ') {
b[j] = a[i];
printf("%c ",b[j]);
j++;
}
else if (a[i] == ' ') {
b[j] = '\0';
if (strlen(b) > l1) {
strcpy(c,b);
l1 = strlen(b);
}
j = 0;
}
else {
printf("\nEOF");}
}
}
printf("\nlongest is \n");
printf(c);
}
|
|
|
|
|
Try
#include <stdio.h>
enum State
{
INSIDE_BLANKS,
INSIDE_WORD
};
void find_longest_word( const char * a, const char ** pps, const char ** ppe);
int main()
{
const char * foo = "alpha beta gamma delta epsilon ";
const char *ps, *pe;
find_longest_word( foo, &ps, &pe);
if ( pe-ps > 0)
{
printf("longest word length = %ld\n", (pe-ps));
while (ps != pe)
{
printf("%c", *ps);
++ps;
}
printf("\n");
}
return 0;
}
void find_longest_word( const char * a, const char ** pps, const char **ppe)
{
const char * ps = a;
const char * pe = a;
*pps = *ppe = a;
enum State state = INSIDE_BLANKS;
while ( *a != '\0')
{
if ( state == INSIDE_BLANKS)
{
if ( *a != ' ')
{
state = INSIDE_WORD;
ps = a;
}
}
else {
if ( *a == ' ')
{
pe = a;
if ( pe - ps > *ppe - *pps)
{
*pps = ps;
*ppe = pe;
}
state = INSIDE_BLANKS;
}
}
++a;
}
if ( state == INSIDE_WORD)
{
if ( pe - ps > *pps - *pps)
{
*pps = ps;
*ppe = pe;
}
}
}
|
|
|
|
|
Hi. I have a problem when I am trying to convert CString to CByteArray. Here is the code, and the result:
CByteArray arrByte2;
BYTE* pByteArray = (PBYTE)(LPCTSTR)sSerial;
arrByte2.SetSize(sSerial.GetLength());
memcpy(arrByte2.GetData(), pByteArray, m_sSerial.GetLength());
these values, sSerial, pByteArray and arrByte2 are taken from VS debugger.
Why arrByte2 are having "ýýýý««««««««" on tail ? What I am missing here ?
Thank you for any hint.
modified 9-Jan-18 6:25am.
|
|
|
|
|
It looks like the VS debugger is dumping out additional (or the allocated) memory. Is it for exactly the posted code? Or is arrByte2 declared somewhere else and has been used before?
You are also copying m_sSerial.GetLength() bytes while the array size has been set to sSerial.GetLength() . If m_sSerial is a longer string, you will have a buffer overrun.
Finally, your casting should be
const BYTE* pByteArray = reinterpret_cast<const BYTE*>(sSerial.GetString()); That will at least keep the constness of the string but fail too for Unicode builds when sSerial is not explicitly declared as CStringA .
You might call arrByte2.GetSize() and ignore the additional output if that is as expected.
|
|
|
|
|
Flaviu2 wrote: Why arrByte2 are having "ýýýý««««««««" on tail ? What I am missing here ?
Thank you for any hint.
It does NOT have this trash "on tail". This trash is behind the arrByte2.
Debugger interprets its content as characters and cannot find the actual "end" of array since you did not copy the terminated NULL from the CString.
|
|
|
|
|
You need to copy the length of the string + 1 to get the ending '\0' to terminate a C string
Very basic .. without it the string keeps going in C terms which is exactly what the debugger is showing with rubbish that was in the buffer.
In vino veritas
|
|
|
|
|
Thank you all of you. Yes, that was the problem, I should put
arrByte2.SetSize(sSerial.GetLength() + 1);
|
|
|
|