For example, there is a function named CreateFrame like,
virtual STDMETHODIMP CreateFrame(THIS_ LPCSTR Name,
LPD3DXFRAME*ppNewFrame);
I think STDMETHODIMP means It will return HResult and stdcall function,
but I don't know what THIS_ in argument menas.
THIS_ is defined in combaseapi.h like this.
#define PURE = 0
#define THIS_
#define THIS void
For more information, the function 'CreateFrame ' is called automatically when
D3DXLoadMeshHierarchyFromX is called.
Those are just old-school COM macros. Don't worry about them, especially since you are looking at the deprecated D3DX header for legacy Direct3D 9 from 13+ years ago...
virtual STDMETHODIMP Func(THIS);
This is a function that takes ONE parameter: the implicit this pointer, returns an HRESULT, and is annotated for proper COM calling convention __stdcall.
virtual STDMETHODIMP Func(THIS_ LPCSTR Name, LPD3DXFRAME*ppNewFrame);
This is a function that takes THREE parameters: the implicit this pointer, a pointer to a string, and a pointer to a specific object), returns an HRESULT, and is annotated for proper COM calling convention.
To declare a function that returns a type other than HRESULT you'd use STDMETHOD_:
virtual STDMETHOD_(ULONG, Func) (THIS_ LPCSTR Name, LPD3DXFRAME*ppNewFrame);
These old headers often also supported use from C rather than C++, where this is not implicit. Legacy D3DX never bothered with the C call-paths, but many old system headers did use them. In fact, if you did a little further in combaseapi.h you'll see the C language section defines THIS_ and THIS as:
#define PURE
#define THIS_ INTERFACE FAR* This,
#define THIS INTERFACE FAR* This
The more modern MIDL compiler generates code that's slightly less confusing:
virtual HRESULT STDMETHODCALLTYPE Func(void);
or
virtual void STDMETHODCALLTYPE Func(UINT value, LPCWSTR name);
Related
I have a Windows Form in Visual Studio C++. (CLR)
In the header file, I declare void createThread()
private:
void createThread() {
char buffer[1024];
ZeroMemory(buffer, sizeof(buffer));
while (true) {
recv(connection, buffer, sizeof(buffer), 0);
main.displayMessage(gcnew System::String(buffer));
}
ExitThread(0);
}
Now, I want to call function createThread
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)createThread, NULL, NULL, NULL)
After that I get this error:
a pointe-to-member is not valid for a managed class
I tried user thread library but not support. How can I fix??
It appears that this function is defined in a managed class. You need to use the managed thread object, not unmanaged CreateThread.
This error exists for two reasons: First, it's a instance method, not a static method, so it would need to be called with an instance of this type, which there's no way to pass to CreateThread. Second, it's a managed object, and its methods do not trivially convert to C-style raw function pointers.
Finally, a note about the language: C++/CLI is meant to act as a way to interface managed code (e.g., C#) with unmanaged C++. It's not intended as a primary development language. If you don't need to link managed and unmanaged code, you may want to consider switching to either C# or C++ for your application.
I have some functions in a COM interface that return different success values via the HRESULT, but using the space that is defined as "successful" (i.e. SUCCEEDED(hr) is non-zero).
For example
HRESULT MyMessageBox( BSTR title /*[in]*/, BSTR text /*[in]*/, long buttons /*[in]*/ );
a function that displays a dialog similar to a MessageBox; it returns an indicator of which button the user used to dismiss the dialog. (I defined an enum for this with values within the space of HRESULTs which is reserved for user-defined codes).
This is fine in a C++ client; however when VB is the client, or Java wrappers such as JACOB, it appears to intercept the HRESULT and there is no way that the client can tell which successful code occurred.
Is it actually a terrible design to have the HRESULT indicate anything other than 0 or exceptions ; should I instead make new functions that have an [out] parameter to get which button is used?
Most language runtimes will map an HRESULT to an exception, makes writing COM code a lot easier. And yes, they'll ignore positive values. They might have an escape for that, in .NET the [PreserveSig] attribute suppresses the exception mapping and exposes the HRESULT return value as an int.
But that's painful and unnecessary. They will also map an argument that you decorate as [out, retval] to the function return value. Which is what you are looking for here:
HRESULT MyMessageBox([in] BSTR title, [in] BSTR text, [in] long buttons,
[out,retval] long* result);
And now the client programmer can write something like this:
int result = yadayada.MyMessageBox("title", "text", 0);
Giving you the opportunity to use the HRESULT only for "function failed" return values, S_OK otherwise. You can further improve it by using enum types to name the legal button and return values.
I am using DMD64 D Compiler v2.063.2 on Ubuntu 13.04 64-bit.
I have written a class as below:
class FixedList(T){
// list
private T[] list;
// number of items
private size_t numberOfItems;
// capacity
private size_t capacity;
// mutex
private Mutex listMutex;
// get capacity
#property public size_t Capacity(){ return capacity; }
#property public shared size_t Capacity(){ return capacity; }
// constructor
public this( size_t capacity ){
// initialise
numberOfItems = 0;
this.capacity = capacity;
writeln("Cons Normal");
}
// constructor
public shared this( size_t capacity ){
// initialise
numberOfItems = 0;
this.capacity = capacity;
// create mutex
listMutex = cast(shared)(new Mutex());
writeln("Cons Shared");
}
}
While class is written in this way, in main function, I wrote that code:
auto list1 = new shared FixedList!int( 128 );
auto list2 = new FixedList!int( 128 );
Output with this, there is no error at all and the output is as below:
Cons Shared
Cons Normal
What I do next is to remove both writeln lines from the code, and when I recompile the code, it starts showing error messages as below:
src/webapp.d(61): Error: constructor lists.FixedList!(int).FixedList.this called with argument types:
((int) shared)
matches both:
lists.d(28): lists.FixedList!(int).FixedList.this(ulong capacity)
and:
lists.d(37): lists.FixedList!(int).FixedList.this(ulong capacity)
src/app.d(61): Error: no constructor for FixedList
src/app.d(62): Error: constructor lists.FixedList!(int).FixedList.this called with argument types:
((int))
matches both:
lists.d(28): lists.FixedList!(int).FixedList.this(ulong capacity)
and:
lists.d(37): lists.FixedList!(int).FixedList.this(ulong capacity)
src/app.d(62): Error: no constructor for FixedList
make: *** [all] Error 1
Basically writeln function is preventing the error. Actually writeln is preventing in many places and I am not sure about why this is happening.
I even tried to compile the the code with m32 flag for 32-bit, but it is still same. Am I doing something wrong, or is this a bug?
pure, nothrow, and #safe are inferred for template functions. As FixedList is templated, its constructors are templated. writeln is not (and cannot be) pure as it does I/O. So, while writeln is in the constructors, they are inferred to not be pure, but everything else that the constructors are doing is pure, so without the calls to writeln, they become pure.
Under some circumstances, the compiler is able to alter the return type of pure functions to implicitly convert it to immutable or shared. This works, because in those cases, the compiler knows that what's being returned is a new, unique object and that casting it to immutable or shared would not violate the type system. Not all pure functions qualify, as the parameter types can affect whether the compiler can guarantee that the return value is unique, but many pure functions are able to take advantage of this and implicitly convert their return value to immutable or shared. This is useful, because it can avoid code duplication (for different return types) or copying - since if the type returned doesn't match what you need with regards to immutable or shared, and you can't guarantee that it's not referred to elsewhere, you have to copy it to get the type that you want. In this case, the compiler is able to make the guarantee that the object is not referred to elsewhere, so it can safely cast it for you.
Constructors effectively return new values, so they can be affected by this feature. This makes it so that if a constructor is pure, you can often construct immutable and shared values from it without having to duplicate the constructor (like you'd have to do if it weren't pure). As with other pure functions, whether this works or not depends on the constructor's parameter types, but it's frequently possible, and it helps avoid code duplication.
What's causing you problems is that when FixedList's constructors are both pure, the compiler is able to use either of them to construct a shared object. So, it doesn't know which one to choose, and gives you an ambiguity error.
I've reported this as a bug on the theory that the compiler should probably prefer the constructer which is explicitly marked as shared, but what the compiler devs will decide, I don't know. The ability to implicitly convert return values from pure functions is a fairly new feature and exactly when we can and can't do those implicit conversions is still being explored, which can result both in unanticipated problems (like this one probably is) as well as compiler bugs (e.g. there's at least one case with immutable, where it currently does the conversion when it shouldn't). I'm sure that these issues will be ironed out fairly quickly though.
A pure constructor can build a shared object without being marked shared itself.
Apparently, pureness is inferred for constructors.
writeln is not pure. So, with it in place, the constructors are not pure.
When writeln is removed, the constructors become pure. Both constructors now match the shared call.
I was just fooling around in Xcode and I discovered that the following statement compiles and it doesn't even raise a warning let alone an error:
static static static int static long static var[5];
What's up with that? Does this make it super-DUPER static? :)
All joking aside, why does the compiler permit repeating the static modifier? Is there actually a reason to allow people to do this or were the people who wrote the compiler too lazy to make this raise an error?
I'm not an Objective-C developer, but does the language allow for an arbitrary ordering of modifiers (e.g. static volatile extern)? If so, then it's probably a benign bug in the compiler that after reading a modifier ("static" in this case) returns to a state where it accepts any modifier terminal again, and will do until it encounters the variable's type. Continual static declarations wouldn't contradict any prior modifiers so it wouldn't raise any errors; so based on this I would expect volatile volatile volatile int x; to also work.
For C 2011, The following applies:
Section 6.7.1 Paragraph 2
At most, one storage-class specifier may be given in the declaration specifiers in a declaration, except that _Thread_local may appear with static or extern.
And storage class specifiers are defined as:
storage-class-specifier:
typedef
extern
static
_Thread_local
auto
register
So for C 2011, that should be illegal.
As to Objective C, I have no idea where to find a language specification, so I can't help you there.
I building Wrapper in C++/CLI for C Static library to be used in .NET application through C#
I have function like this in C
long My_COM_Interface( PVOID hDevice,IUnknown **pUnknown);
How to declare IUnknown ** in C++/CLI
for first argument I am using IntPtr but Not able to find out the Replacement for IUknown.
I have another COM Data type GUID in another function this is also an issue for me.
Please Help me find the relacement for data type IUnknown and GUID.
There is no replacement.
C++/CLI understands native types just fine. Include the right header files, and you can use IUnknown* like always.
I'd refer to the APIs, e.g.
public static IntPtr GetIUnknownForObject(Object o);
This API can simply be used from C++/CLR and suggests you should use IntPtr^
try using parameter like;
ref object pUnknown
and use it like
MyObject o = pUnknown as MyObject