I would like to use some nss3.dll code in my program. To do this I decided to declare all of the compound datatypes that it needs and call the functions inside the dll file with them.
I am using a file in the firefox source code to see how to properly use the functions I need. In one of the functions it declares one of these compound datatypes (secuPWData) and passes it variables. Here is the definition I pasted into my code without any errors:
typedef struct {
enum {
PW_NONE = 0,
PW_FROMFILE = 1,
PW_PLAINTEXT = 2,
PW_EXTERNAL = 3
} source;
char *data;
} secuPWData;
The declaration of this struct looks like this in the code I'm looking at: secuPWData pwdata = { PW_NONE, NULL };
When I try to use a similar (or even the same) declaration, it complains about the PW_NONE attribute, claiming it is undefined. When I tried to pass in the 0 value in its place, it told me that 'a value of type "int" cannot be used to initialize an entity of type "enum secuPWData::"'. To try to debug the issue, I tried pasting the definition right on top of the declaration, without any change.
What is causing this problem to occur?
Thanks for any help.
just as #n.m. mentioned try using secuPWData::PW_NONE
#include <iostream>
using namespace std;
typedef struct {
enum {
PW_NONE = 0,
PW_FROMFILE = 1,
PW_PLAINTEXT = 2,
PW_EXTERNAL = 3
} source;
char *data;
} secuPWData;
int main() {
secuPWData pwdata = { secuPWData::PW_NONE, NULL };
return 0;
}
worked for me .. ideone - link
Related
I have been looking everywhere for this question, but I cannot seem to get the answer for this.
So, every example I have been to is simply how to grab function pointers from SO file, which I have done. However, let just say I have this compiled as my .SO file:
(these codes compiled into libsampleso.so):
sampleso.hpp:
#IFNDEF SAMPLESO_HPP__
#DEFINE SAMPLESO_HPP__
struct carDescriptor
{
const char* model;
int prod_year;
int wheel_num;
const char* license_plate;
const char* colour;
} car;
carDescriptor fillCarID(void);
#ENDIF
sampleso.cpp:
#include "sampleso.hpp"
//Struct car fillup function
carDescriptor fillCarID(void)
{
car.model = "Ford Fiesta";
car.prod_year = 2014;
car.wheel_num = 4;
car.colour = "Midnight Blue";
car.license_plate = "D 1234 ABC";
return car;
}
now, compiled, I've got these out of objdump -T libsampleso.so: car (the struct) and _Z9fillCarIDv (the function).
if the return value of _Z9fillCarIDv() (aka fillCarID()) is normal datatype (e.g. string or int), it's easy with dlsym. However, for this I need to cast the struct first and then the function. I've tried creating an empty struct, and then cast dlsym to it:
struct carDesc * cars;
cars = reinterpret_cast<struct carDesc*>(dlsym(hHandler,"car"));
but seems to be impossible to use that as the datatype for the function:
carDesc(*__fn_fillCarIDv)(void);
__fn_fillCarIDv = reinterpret_cast<carDesc(*)(void)>(dlsym(hHandler,"_Z9fillCarIDv"));
cars = __fn_fillCarIDv(); //doesn't work, error: function returns incomplete type "carDesc" C/C++(862)
Anyone ever tried to grab a struct using dlsym without .h file?
Also, how do you deal with the elements from the struct grabbed by dlsym? I know that you don't have the proper elements listed without .h file, and obviously some pointer shifting is necessary, but can anyone give me an example of how to do it?
Thanks
I have some functions that can return either success or one of a fixed set of error codes. To identify the error codes, I had (something like) this old-school C-style enum declared:
enum {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
typedef int my_status_t;
my_status_t MyFunc(); // returns a RESULT_* value
This worked pretty well; the calling pattern would be something like:
if (MyFunc() != RESULT_SUCCESS) printf("Error!\n");
... however it was uncomfortably permissive about allowing implicit conversions of my_status_t values to int/bool/etc, allowing careless mistakes like this:
// Compiles but does the wrong thing at run-time -- bad!
if (MyFunc() == false) printf("Error!\n");
... so in my new code revision, I converted it to be an enum class instead:
enum class my_status_t {
RESULT_ERROR_BAD_PARAMETER = -3,
RESULT_ERROR_FILE_NOT_FOUND = -2,
RESULT_ERROR_GENERAL = -1,
RESULT_SUCCESS = 0
};
... this works great from a compile-time checking perspective; now most unintentional type-promotions are caught by the compiler, forcing the programmer to go back and do it the right way.
The only thing that bothers me is that the new syntax is tedious: now I have to write something like:
if (MyFunc() != my_status_t::RESULT_SUCCESS) printf("Error!\n");
... at every call site -- having to type out my_status_t:: each time is tedious and makes the code harder to read, without really adding much value (since RESULT_SUCCESS is sufficiently unique for my purposes on its own, anyway)
My question is, is there some kind of using namespace my_status_t; style directive I could use to tell the compiler to export the enum-values out of their my_status_t namespace, so that I could reference them without having to type the my_status_t:: prefix all the time?
If you going to be typing a lot more of the nuisance scope-prefixes than there
are constants in the enum class, then it may be worth your while to go with this
way:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
constexpr result RESULT_ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER;
constexpr result RESULT_FILE_NOT_FOUND = result::ERROR_FILE_NOT_FOUND;
constexpr result RESULT_ERROR_GENERAL = result::ERROR_GENERAL;
constexpr result RESULT_SUCCESS = result::SUCCESS;
result foo() {
return RESULT_SUCCESS;
}
int main()
{
switch (foo())
{
case RESULT_SUCCESS:
;
}
// ^ warning: enumeration value ‘...’ not handled in ...
if (foo() == RESULT_SUCCESS) {
return 0;
}
/* error: no match for ‘operator==’
if (foo() == false) {
return -1;
}
*/
}
(g++ -Wall -Wextra -pedantic -std=c++11)
Do this change:
enum class result {
ERROR_BAD_PARAMETER = -3,
ERROR_FILE_NOT_FOUND = -2,
ERROR_GENERAL = -1,
SUCCESS = 0
};
because your enumerated values are in a scope, you no longer have to give them as long a name.
Now your code becomes:
if (MyFunc() != result::SUCCESS) printf("Error!\n");
which is a whole 1 character longer than before.
You could also
using my_status_t = result;
if you are tied to my_status_t as a type name.
As of C++17 there is no way to cleanly avoid the result:: prefix. There is talk about using ERROR_BAD_PARAMETER = result::ERROR_BAD_PARAMETER; or the like in later versions of C++, but I'm unaware if they are going to get into c++20.
Here's a way:
enum class my_status_t { };
inline constexpr my_status_t RESULT_ERROR_BAD_PARAMETER = my_status_t(-3);
// add other enum values here
Unfortunately, this way you lose some good properties of enum. Like compiler can warn you if you don't handle a value in a switch (and don't forget to set the underlying type of enum class, if you have big values).
So I actually don't recommend this way (I better like Yakk's solution), but maybe this answer can help you anyway...
I saw someone writing code like this , in a C++ class:
int foo ( int dummy )
{
this->dummy = dummy;
}
Shall we use code like that , will it cause problems ?
I tried to compile something like this , it seems to be worked.
#update:
I posted this mostly about the name dummy , and the internal variable this->dummy , and if it's problem causing
That's perfectly fine for a member function, other than you're missing a return statement. dummy will shadow the member variable and so you use this-> to refer to member.
int foo ( int dummy )
{
this->dummy = dummy; // set member to argument
return this->dummy;
}
Don't do this for things more complex than a simple set function, as it's confusing.
int foo ( int dummy ) // Bad practise! Rename this param as the function isn't a setter
{
this->dummy = dummy * 2 + 1;
return this->dummy;
}
There is nothing wrong with doing that perse. It can get confusing though if you use dummy assuming it is coming from the class but its actually coming from the parameter.
IMO, its better to use something to denote it is a class member. Some people use simply mDummy, other m_Dummy, others just write dummy_.
Its up to you what you prefer but most of all you should be consistent.
The code is not fine. The function is defined as returning an int but there is no return statement. The compiler might only give a warning about this, but the function calling foo might expect it to return a valid value, which it doesn't, and bad stuff might happen.
You have to do it this way if you're passing a parameter with the same name as the member variable.
But it might be a better practice to avoid a hidden (member-)variable by using different names. There's different coding styles, some would use dummy_, some would use mDummy or other ways to name member variables. This makes your code less confusing.
Well there is nothing wrong with your use, but the code needs to return an int as its an int function :)
Dummy variable in your current class is assigned to the passed int, however do remember they are different but now pointing to the same thing, therefore its better to give it a different name as its in a different.
You could however loose precision under certain variable types.
#include <stddef.h>
typedef struct intlist {
int size;
int i[1];
} intlist;
intlist *
makeintlist (int size)
{
intlist *ilp = malloc (offsetof (intlist, i[size])); /* not C++ */
ilp->size = size;
return ilp;
}
member variable size is allocated to size
That will work.
Don't do it, it's confusing!
I've searched stackoverflow for an answer but I cannot get something relevant.
I'm trying to initialize a static structure instance with initial values by specifying their tags, but I get an error at compilation time:
src/version.cpp:10: error: expected primary-expression before ‘.’ token
Here's the code:
// h
typedef struct
{
int lots_of_ints;
/* ... lots of other members */
const char *build_date;
const char *build_version;
} infos;
And the faulty code:
// C
static const char *version_date = VERSION_DATE;
static const char *version_rev = VERSION_REVISION;
static const infos s_infos =
{
.build_date = version_date, // why is this wrong? it works in C!
.build_version = version_rev
};
const infos *get_info()
{
return &s_infos;
}
So the basic idea is to bypass the "other members" initialization and only set the relevant build_date and build_version values.
This used to work in C, but I can't figure out why it won't work in C++.
Any ideas?
edit:
I realize this code looks like simple C, and it actually is. The whole project is in C++ so I have to use C++ file extensions to prevent the makefile dependency mess ( %.o: %.cpp )
The feature you are using is a C99 feature and you are using a C++ compiler that doesn't support it. Remember that although C code is generally valid C++ code, C99 code isn't always.
The following example code defines a struct in what I consider a more C++ way (no need for typedef) and uses a constructor to solve your problem:
#include <iostream>
#define VERSION_DATE "TODAY"
#define VERSION_REVISION "0.0.1a"
struct infos {
int lots_of_ints;
/* ... lots of other members */
const char *build_date;
const char *build_version;
infos() :
build_date(VERSION_DATE),
build_version(VERSION_REVISION)
{}
};
static const infos s_infos;
const infos *get_info()
{
return &s_infos;
}
int main() {
std::cout << get_info()->build_date << std::endl;
std::cout << get_info()->build_version << std::endl;
return 0;
}
I believe this was added as a feature in C99, but has never been a standard feature in C++.
However, some compilers probably offer it as a non-standard language extension.
I see that this is part of CPP 20 standard now. It is called Designated initializers.
T object = { .des1 = arg1 , .des2 { arg2 } ... }; (3) (since C++20)
T object { .des1 = arg1 , .des2 { arg2 } ... }; (4) (since C++20)
Here's the deal. I have a static class which contains several static functions used for getting input. The class contains a private static member variable for indicating whether the user entered any information. Each input method checks to see whether the user entered any information, and sets the status variable accordingly. I think this would be a good time to use the ternary operator. Unfortunately, I can't, because the compiler doesn't like that.
I replicated the problem, then simplified my code as much as was possible to make it easy to understand. This is not my original code.
Here's my header file:
#include <iostream>
using namespace std;
class Test {
public:
void go ();
private:
static const int GOOD = 0;
static const int BAD = 1;
};
Here's my implementation with the ternary operator:
#include "test.h"
void Test::go () {
int num = 3;
int localStatus;
localStatus = (num > 2) ? GOOD : BAD;
}
Here's main function:
#include <iostream>
#include "test.h"
using namespace std;
int main () {
Test test = Test();
test.go();
return 0;
}
When I try to compile this, I get this error message:
test.o: In function `Test::go()':
test.cpp:(.text+0x17): undefined reference to `Test::GOOD'
test.cpp:(.text+0x1f): undefined reference to `Test::BAD'
collect2: ld returned 1 exit status
However, if I replace this:
localStatus = (num > 2) ? GOOD : BAD;
with this:
if (num > 2) {
localStatus = GOOD;
} else {
localStatus = BAD;
}
The code compiles and runs as expected. What obscure C++ rule or GCC corner case is responsible for this lunacy? (I'm using GCC 4.4.1 on Ubuntu 9.10.)
This is according to the C++ Standard. The ternary operator does constitute a single lvalue that will refer to either GOOD or BAD at runtime. The lvalue to rvalue conversion is not applied immediately to either the lvalue GOOD or BAD, and therefor you require a definition of GOOD and BAD.
See the core language issue report http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#712 .
As a workaround, you can apply explicit casts to int (which reads their values, thereby doing an lvalue to rvalue conversion) or use an operator that reads the value, like +:
localStatus = (num > 2) ? +GOOD : +BAD;
class Test {
static const int GOOD = 0;
static const int BAD = 1;
};
These are only declarations; they are not definitions. You need to provide definitions of the static member variables, outside of the definition of the class, in one of your .cpp files:
const int Test::GOOD;
const int Test::BAD;
Alternatively, for integer constants, it is often more convenient to use an enum:
class Test {
enum {
GOOD = 0,
BAD = 1
};
};
Your code looks fine to me. And ideone agrees: see this link. But that's with gcc-4.3.4. However, my gcc-4.4.0 doesn't accept it. So whatever the reason, it's not obvious.
Edited to add: The following variant compiles under gcc-4.4.0:
int localStatus = 42 ? GOOD : BAD;
Reminder: the following code doesn't compile:
int localStatus = (num == 42) ? GOOD : BAD;
So somebody has screwed up somewhere.