how to set values in attribute of Active directory using C++? - c++

I am using the ldap_modify function to change an attribute value using C++ ...
msgid=ldap_modify_ext_s( ld, dnNameval, ldapmod,NULL,NULL );
The problem is the mod_val argument in that function ...
LDAP *id;
dnNameval ="distinguised name";
In the ldapmod there are three values ...
mod_type="attribute to be changed";
mod_op=LDAP_MOD_REPLACE;
ldapmod struct
The ldapmod struct is:
typedef struct ldapmod {
int mod_op;
char *mod_type;
union {
char **modv_strvals;
struct berval **modv_bvals;
} mod_vals;
#define mod_values mod_vals.modv_strvals
#define mod_bvalues mod_vals.modv_bvals
} LDAPMod;
I tried passing the value like this:
mod_vals=(PWCHAR*){"bala",Null};
which resulted in the error
error C2679: binary '=' : no operator found which takes a right-hand operand
of type 'PWCHAR *' (or there is no acceptable conversion)
I also tried this:
mod_vals.modv_strvals=(PWCHAR*) Password1;
mod_vals.modv_bvals=NULL;
but then the array has a null value...
Can anyone help me work out how to pass the values in that variable? Do I need to include any additional header files? I am already using the winldap.h header.
Thanks in advance.

This won't work:
mod_vals = (PWCHAR*){"bala",Null};
You can't assign a value to a union that way. You have to specify which of the members of the union you want to write to. Also, (PWCHAR *) is the wrong type; you're not dealing with wide characters. Even if you were, you can't convert a string just by casting it.
This won't work either:
mod_vals.modv_strvals=(PWCHAR*) Password1;
mod_vals.modv_bvals=NULL;
The modv_strvals member is a pointer-to-pointer, not just a pointer, and it doesn't make sense to write to two members of a union; they're mutually exclusive. Depending on context you either use modv_strvals or modv_bvals, never both.
You probably want to do this:
mod_vals.modv_strvals = {"bala", Null};

Related

Indeterminate return type of a function

I'm developing a parser of Adobe Type 1 font, using C++ language. And there is a problem when I tried to decode the DICT Data.
The operands in the DICT, which are stored as byte-sequence in the PDF file, may be either integer or real number.
I defined a function, whose prototype is getOperandVal(unsigned char* buf), to decode the sequence to number. And the problem appeared.
Before parse the buf, we can not know the buf is real or integer number. So I can not determine the return-value type, which should be int or double.
A solution is to use a struct as the return-value type. The struct is like below:
typedef struct
{
int interger;
double real;
bool bReal;
}RET;
Then the function prototype is:
RET getOperandVal(unsigned char* buf);
But I think it is not compact. First of all, it is inconvenient to use. Second, the program will run slower when the size of data is big.
Can anyone give me a better solution? Can template do it?
Thank you very much!
Addition:
The program will transfer the operands value into byte-sequence for rewriting into file after edit. Consider the requirement, please.
You can't use templates because you don't know at compile time what type will be returned.
But you can use a union:
struct Int_real {
union {
int integer;
double real;
};
bool is_real;
};
A very good idea is to improve upon it by making it safe (allow access to only the field of the union that is active).
Pretty soon (hopefully), you will be able to use std::any
Template types are evaluated at the compile time, you could not change function prototype dynamically. You could either upscale return value to the biggest size (for example always return double), return a struct or use some variant implementation, like boost::variant.

C++ wstring to enum

I have defined an enum like this:
enum eFeature
{
eF_NONE=0,
eF_PORT_A=1,
eF_PORT_B=2,
eF_PORT_C=3,
};
I would now like to convert a wstring (which is either "0", "1", "2" or "3") to eFeature.
I tried
eFeature iThis;
iThis = _wtoi(mystring.c_str());
But the compiler tells me "A value of type 'int' can not be assigned to an entity of the type eFeature."
Can somebody help?
Thank you.
You are attempting to assign an int to an enum, which is not allowed. Leaving the wstring distraction aside, what you are doing is the equivalent of
eFeature iThis;
iThis = 42;
You first need to cast the int to the enum type:
eFeature iThis;
iThis = static_cast<eFeature>(42);
Obviously, you would need to perform some kind of range checking first.

error when declaring an enum to a variable

I have the following syntax:
enum home
{
no,
yes,
}homew;
home homes;
std::string s;
s="no";
homes=s; //is not working. Why?
Were am I wrong?
You are confusing strings with enumerated values.
An enum variable is simply an integer that you can use a literal for at compile time, nothing more than that.
It makes the code more understandable and self-documenting rather than merely using a number literal.
This
enum home { no, yes, } homew;
defines the type home plus a variable homew of that type.
Did you intent that? Why?
The values defined for an enum type are literals, to be used as such:
home homes = no;
In C++ there's no built-in way to convert between enum value literals and a string representation of them. If you need this, you'll have to cook up your own.
enums in C++ are implicitly an int data type. You can't assign string values to enum.
It doesn't compile because C++ provides no built-in mechanism for converting from std::string to an enum.
typeof(home) != typeof(std::string) // types are not equal
Thus, you cannot assign an enum to std::string or otherwise. Implicit conversion between enum and integral types like bool, int etc. is possible however.
Is there a way I can solve my problem as it is?
If possible use std::map.
std::map<std::string, home> myTypes;
myTypes["yes"] = yes;
myTypes["no"] = no;
Now you can do,
homes = myTypes["no"];
As others pointed out, enums values are of int type. You could instead write a small function that converts from enum to String like this:
std::string GetStringFromEnum(home iHome)
{
switch (home)
{
case yes: return "yes";
case no: return "no"; break;
default: return "here be dragons";
}
}
and vice-versa:
home GetEnumFromString(std::string iImput)
{
if (iImput == "yes") return yes;
return no; //if you extend the enum beyond 2 values, this function will get more complicated
}
and you could modify your code like so:
homes = GetStringFromEnum(no)
the downside for this approach is that if you modify the enum, you must also modify the convert function.
HTH,JP

how to use strcat with an ENUM?

I have an external tool which is generating an ENUM based on user inputs. Now this ENUM is being used by my C++ code where in i have to select a particular ENUM based on a variable say 'x'. The ENUMS generated are of the form 'ENUM_1', 'ENUM_2', 'ENUM_3'....so on. Now I want the code inside my code such that the appropriate ENUM is chosen based on 'x'. I tried using the strcat function like:
typedef enum ( enum_1, enum_2, enum_3...enum_n) map1;
y=(map1)strcat("enum_", x);
but it gives me the error "Cannot convert from char* to map1.
Can someone pls suggest a method of achieving this.
ThankYou
You can't do this using strcat. From the description what I understand is that you want to convert x to map1. To achieve this, you can do map1 m = (map1)(x-1); See this sample code:
typedef enum { enum_1, enum_2, enum_3} map1;
int main()
{
int x = 1;
map1 m = (map1)(x-1);
}
-1 is required because, the integer value of the enums in map1 starts from 0.
You can't do this. Well you can't do it this way...
Enums aren't evaluated by name at compile time. You'll have to try something with the preprocessor. You can create a define to do something similar. Something like:
#define fn(x) enum_##x
And then call
fn(x)
But this happens when the file gets preprocessed. So you can't access runtime variables. Judging by your code I don't think you'll be able to do what you want.
Good luck though.
Now I want the code inside my code such that the appropriate ENUM is chosen based on 'x'.
Enumerated values are constants and based on the statement I assume that x is an integer data type.
y=(map1)strcat("enum_", x);
strcat(..) passing parameters should be of type char*. And clearly x is not of type char* based on previous statement. It not clear why are you using strcat for achieving this task.
Answer for your subject line: No. You cannot use strcat with enumerated values.

Type casting in c++

In c++ can we cast an object to an integer ?
Clarifying my question - Suppose I have created an interface to handle file management task like create file, open file, read, write and I want to have one unique handle for every instance of a file. To achieve this can I create a file handle for each instance of the file interface by just type casting that instance to integer ?
To all - I hope now i am clear.
Not all objects. Every object in C++ has a type. That type of an object defines whether a cast to int exists, and if so, what algorithm is used.
If you have an object and want to cast it to int then you need to explicitly provide operator int for that class.
class File
{
public:
...
...
operator int() { return int(this); }
...
}
Then
File myFile;
int myFileHandle = myFile;
I would rather convert to a long type. This is safer when a pointer value is converted to an integral type on an x64 machine. You can just use reinterpret_cast<long>(myInterfacePointer) in that case.
you can, but it depend on the sizeof(YourObject) compared to sizeof(int), by casting any object to int you will access the first 4 bytes part of your object (assuming sizeof(int) == 4), if your object is smaller than sizeof(int) somewhere you will get access violation or crash. to cast :
`
MyObject object;
int castedObject = *((int*)&object);
`
to cast without pointer intermediate, you must provide typecast operator inside MyObject class. or you can declare global static function of int& operator=(const MyObject& object){...}
Edit: Since you are mapping files to a unique handle, you can use a std::vector<std::string> or a vector<shared_ptr<fstream> > or a vector<FILE*>.
On a POSIX-compliant system there is also fileno to convert a FILE* into its file descriptor which is an int.
To get the hash: Use the hash_value function from boost.
To convert any value to integer lexically: Use the lexical_cast<int> function from boost
To cast the value to integer: Just use (int)value.
For the above to work, the class you're going to convert needs to implement some special member functions e.g. operator<< and operator int.
To convert an object into an arbitrary unique integer, use (int)&value.
To get a random integer, use rand().
Why not just get the file descriptor/handle/whatever ID from the operating system and use that? Most systems have some kind of concept like that.
Consider using void * instead of int for the handles if you really want them to be pointers. Then casting a pointer-to-object to a handle is easy, and you can still hide the implementation away.
In response to #potatoswatter's comment to my first response.
I don't like the idea of casting objects. I would rather use a hashing function that produces an integer hash, say based on the filename or read/write flags. Now, I have to post another answer
class File
{
public:
...
...
operator int();
...
private:
char fileName[];
int flags;
};
The integer conversion operator is now a hashing function:
File::operator int()
{
int hash = 0;
int c;
char *str = fileName;
while (c = *str++)
hash += c;
hash += flags;
return hash;
}
I know the hash function is lousy. But you can avoid casts that are lousier and come up with your own hashing function that suits your needs better.