I'm having trouble to find the meaning of his NS_IMETHODIMP in a XPCOM, and I would like to understand this function's signature:
NS_IMETHODIMP myConfig::GetProperty(const char *name, char **_retval NS_OUTPARAM)
{
//...
}
It depends on your platform, but in general it's just a #define for nsresult. On Windows, it's a bit different, and it's a #define for nsresult __stdcall.
Related
I'm quite new to pointers in c.
Here is a snippet of code I'm working on. I am probably not passing the pointer correctly but I can't figure out what's wrong.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
__uint16_t CCrc8();
__uint16_t process_command();
int main () {
//command format: $SET,<0-1023>*<checksum,hex>\r\n
char test_payload[] = "SET,1023*6e";
process_command(test_payload);
return 0;
}
__uint16_t process_command(char *str1) {
char local_str[20];
memcpy(local_str, str1, sizeof(str1));
printf(str1);
printf("\n");
printf(local_str);
}
This results in:
SET,1023*6e
SET,1023
I'm expecting both lines to be the same. Anything past 8 characters is left off.
The only thing I can determine is that the problem is something with sizeof(str1). Any help appreciated.
Update: I've learned sizeof(*char) is 2 on 16bit systems, 4 on 32bit systems and 8 on 64-bit systems.
So how can I use memcpy to get a local copy of str1 when I'm unsure of the size it will be?
sizeof is a compiler keyword. What you need is strlen from #include <string.h>.
The value of sizeof is determinated at compile time. For example sizeof(char[10]) just means 10. strlen on the other hand is a libc function that can determine string length dynamically.
sizeof on a pointer tells you the size of the pointer itself, not of what it points to. Since you're on a 64-bit system, pointers are 8 bytes long, so your memcpy is always copying 8 bytes. Since your string is null terminated, you should use stpncpy instead, like this:
if(stpncpy(local_str, str1, 20) == local_str + 20) {
// too long - handle it somehow
}
That will copy the string until it gets to a NUL terminator or runs out of space in the destination, and in the latter case you can handle it.
This might sound stupid but is there a way to activate support of the inner members of an SSE vector type ?
I know this works fine on MSVC, And I ve found some comments on forums and SO like this.
The question, is can I activate this on CLang at least without creating my own unions ?
Thank you
[edit, workaround]
Currently I decided to create a vec4 type to help me.
here is the code
#include <emmintrin.h>
#include <cstdint>
#ifdef _WIN32
typedef __m128 vec4;
typedef __m128i vec4i;
typedef __m128d vec4d;
#else
typedef union __declspec(align(16)) vec4{
float m128_f32[4];
uint64_t m128_u64[2];
int8_t m128_i8[16];
int16_t m128_i16[8];
int32_t m128_i32[4];
int64_t m128_i64[2];
uint8_t m128_u8[16];
uint16_t m128_u16[8];
uint32_t m128_u32[4];
} vec4;
typedef union __declspec(align(16)) vec4i{
uint64_t m128i_u64[2];
int8_t m128i_i8[16];
int16_t m128i_i16[8];
int32_t m128i_i32[4];
int64_t m128i_i64[2];
uint8_t m128i_u8[16];
uint16_t m128i_u16[8];
uint32_t m128i_u32[4];
} vec4i;
typedef union __declspec(align(16)) vec4d{
double m128d_f64[2];
} vec4d;
#endif
On recent clangs, this Just Works without you needing to do anything at all:
#include <immintrin.h>
float foo(__m128 x) {
return x[1];
}
AFAIK it Just Works in recent GCC builds as well.
However, I should note the following:
Consider carefully whether or not you really need to do element-wise access in your vector code. If you can keep your operations in-lane, they will almost certainly be significantly more efficient.
If you really do need to do a significant number of lanewise or horizontal operations, and you don’t need portability, consider using Clang extended vectors (or “OpenCL vectors") instead of the basic SSE intrinsic types. You can pass them to intrinsics just like __m128 and friends, but they also have much nicer syntax for vector-scalar operations, lane wise operations, vector literals, etc.
I encountered the following code snapshot:
struct hostent *hp;
hp = my_gethostbyname(localhost);
if (hp == NULL) {
ls_syslog(LOG_ERR, I18N_FUNC_FAIL, fname, "my_gethostbyname()");
return -1;
}
strcpy(localhost, hp->h_name);
memcpy(&addr, hp->h_addr, hp->h_length);
I am rather confused by the last statement, the declaration of struct hostent is like this:
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
};
It doesn't have a field named "h_addr", but the code did can compile, can anyone tell me why? thanks.
You missed this bit right under it:
#define h_addr h_addr_list[0] /* for backward compatibility */
So no, there is no problem.
In the GNU libc manual (or see here for the entire libc manual all on one page) they say:
Recall that the host might be connected to multiple networks and have different addresses on each one
They also provide the h_addr variable which is just the first element of the vector h_addr_list.
h_addr is not POSIX. See POSIX netdb.h. Using h_addr could result in error: ‘struct hostent’ has no member named ‘h_addr’. Portable code should use h_addr_list instead.
Note that the h_addr macro is on some systems only visible if you define _BSD_SOURCE and/or _DEFAULT_SOURCE before including header files.
Years ago, I used to do some basic programming in C. Now I am attempting to relearn what I have forgotten as well as learn Visual C++. I am confused though by all the string options and now the extra layer of trying to make my programs Unicode compatible. I have been reading Beginning Visual C++ 2010 as well as online reading to learn this information.
As an exercise I am writing a very basic program that asks a user to input some text and then display that text in the form of a messagebox. The program works, but my way of getting it to work was more through guesswork and looking at other examples than truly understanding why I need to convert the various strings into different types.
The code is:
#include "stdafx.h"
#include <iostream>
#include <string>
#include "Windows.h"
using std::wcin;
using std::wcout;
using std::wstring;
int _tmain(int argc, _TCHAR* argv[])
{
wstring myInput;
wcout << "Enter a string: ";
getline(wcin, myInput);
MessageBoxW(NULL, myInput.c_str(), _T("Test MessageBox"), 64);
return 0;
}
The MessageBox syntax is:
int WINAPI MessageBox(
__in_opt HWND hWnd,
__in_opt LPCTSTR lpText,
__in_opt LPCTSTR lpCaption,
__in UINT uType
);
On the other hand, if I just use the command line argument as the text of the messagebox, I do not need to convert the string at all and I am not sure why.
#include "stdafx.h"
#include <iostream>
#include <string>
#include "Windows.h"
using std::wcout;
int _tmain(int argc, _TCHAR* argv[])
{
MessageBoxW(NULL, argv[1], _T("Test MessageBox"), 64);
return 0;
}
My confusion is:
Why do I need to use the c_str() for argument 2 to MessageBoxW and why do I need to use the _T() macro (?) in argument 3?
Why did the program work in the second code example without doing some sort of conversion?
What exactly does LPCTSTR mean? I see another variant in MSDN functions called LPTSTR.
Thanks!
1) .c_str() is a standard C++ method to convert from C++ strings to C strings. _tmain, _T('x'), _T("text") and _TCHAR are (somewhat ugly) Microsoft macros that make your program compile either in unicode or non-unicode mode. There's a global setting in the project options that set some macros to configure your project in one of these two modes.
If you are in non-unicode mode (referred to as ANSI mode in MS's documentation) the macros expand to:
main, 'x', "text", char
If you are in unicode mode, the macros expand to
wmain, L'x', L"text", wchar_t
2) and 3) Windows headers are full of typedefs and macros like that. Sometimes they make code more obscure thant it needs to be. In general, LP means pointer (long pointer, i guess, but it's been a while since we needed to distinguish between near and far pointers), C means "const", T means that it will be either char or wchar_t depending on project settings and STR is obviously "string". After all, it's a plain C type, that's why you can pass C strings to them without conversion.
The MessageBoxW function is expecting a C-style wide-character string (WCHAR ). The macro _L() alters your string so that it's Unicode compatible (WCHAR instead of char*).
argv[] doesn't do objects, so you're already getting a WCHAR pointer out of it.
LPCTSTR is basically a WINAPI typedef for const char * or const WCHAR*, depending on whether you are building as UNICODE. Also see this post: LPCSTR, LPCTSTR and LPTSTR
In short, your main function is being passed WCHAR* strings and MessageBoxW expects WCHAR* strings.
If I use Marshal::StringToHGlobalAnsi as following:
char *src = (char *)Marshal::StringToHGlobalAnsi(this->Textbox1->Text).ToPointer();
Do I need to use Marshal::FreeHGlobal() ? And if, What parameter should I give ?
According to MSDN - yes, you need to call FreeHGlobal. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.stringtohglobalansi%28v=VS.100%29.aspx:
Because this method allocates the unmanaged memory required for a
string, always free the memory by calling FreeHGlobal
The C# string conversion functions are absolutely horrible by C++ standards.
C++/CLI has its own string conversion helpers, which follow the rules of RAII to automatically clean up temporary buffers. Just use:
#include <stdlib.h>
#include <string.h>
#include <msclr\marshal.h>
using namespace msclr::interop;
marshal_context converter;
const char *src = converter.marshal_as<const char*>(Textbox1->Text);
Attach my 2 practice code for Marshal::FreeHGlobal
Be noted that the argument of Marshal::FreeHGlobal() are different!!
string CPlusPlusString;
String ^VisualString;
VisualString=textBox1->Text;
CPlusPlusString=(char *)Marshal::StringToHGlobalAnsi(VisualString).ToPointer();
Marshal::FreeHGlobal(Marshal::StringToHGlobalAnsi(VisualString));
char *CString;
String ^VisualString;
VisualString=textBox1->Text;
CString = (char*) Marshal::StringToHGlobalAnsi(VisualString).ToPointer();
Marshal::FreeHGlobal(IntPtr(CString));