I have this simple case:
struct ID3D11Buffer;
class Object3D
{
Microsoft::WRL::ComPtr<ID3D11Buffer> indBuffer; // use of undefined type 'ID3D11Buffer' in VisualStudio 2013
std::shared_ptr<ID3D11Buffer> a; // ok
}
As you can see forward declaration works withshared_ptr, but fails with ComPtr. And I curious why?
Related
I need to initialize to a variable only once in C++/CLI class accessible to managed code. Is a managed pointer initialized to nullptr when using gcroot? Specifically will the Initialize function below work as I expect? And only create the MyOtherClass once no matter how many times MyClass::Intialize is called?
class MyClass
{
public:
void Initialize();
private:
#ifdef _MANAGED
gcroot<MyOtherClass^> _myOtherClass;
#endif
};
void MyClass::Initialize()
{
if(_myOtherClass == nullptr)
{
_myOtherClass = gcnew MyOtherClass();
}
}
I'm using Visual Studio 2019. And the managed object accessing this is written in C#. I'm relatively new to CLI code. And I wasn't able to find the answer quickly by Googling it. And I'm sure someone in this community knows the answer.
Managed handles are default initialized to nullptr, per Default initialization: "when handles are declared and not explicitly initialized, they are default initialized to nullptr".
if(_myOtherClass == nullptr)
The above fails to compile with error C2088: '==': illegal for struct because gcroot wraps a GCHandle structure, which cannot be directly compared against nullptr.
To check the target handle (not the wrapper handle), use the following, which works as expected.
if(static_cast<MyOtherClass^>(_myOtherClass) == nullptr)
In a new Rust module, I can write:
struct myStruct {
x : u32
}
impl myStruct {
fn new() -> myStruct{
myStruct{ x : other()}
}
fn other() -> u32 {
6
}
}
Coming from other OO languages, I would expect other() to be in scope for new(). That is, I would expect to be able to call one static method of a class from another static method of the same class. However, rustc produces the message:
error[E0425]: cannot find function `other` in this scope
--> dummy_module.rs:9:23
|
9 | myStruct{ x : other()}
| ^^^^^ not found in this scope
In contrast, the following Java code compiles fine:
public class myStruct{
int x;
public myStruct(){
x = other();
}
private int other(){
return 5;
}
}
I don't recall seeing any mention of this in the Rust book I'm using, and I can't seem to find a clear answer online. I can fix it by explicitly scoping the call to other with myStruct::other(), but this seems cumbersome. If I try use myStruct, then I get the cryptic message
7 | use myStruct;
| ^^^ unexpected token
Is this explicit scoping always required? If so, why?
Am I doing something incorrect? Is there an idiomatic workaround to this?
The Rust designers have made the following choice: everything related to the scope is explicit. So, just as you must type self to call a member function from another member function: self.foo(), you must call a static member with Self: Self::bar().
I think that it is the case because self could not be implicit: indeed it had to be added as a parameter either by value or borrowed, unlike in Java where this is always taken by value. Thus, because self was already an explicit parameter, it was needed as an explicit caller for consistency.
Because of its memory model, Rust expliciteness permit to give better error messages. For example, consider this code:
struct Struct;
impl Struct {
fn foo(&mut self) {
self.consume();
}
fn consume(self) {}
}
The error message is:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:5:9
|
5 | self.consume();
| ^^^^ cannot move out of borrowed content
Then the team made the choice of full expliciteness to maintain the grammar coherent.
Yes it is intended, because rust is not Java ;)
You just can write:
myStruct { x: myStruct::other() }
or
myStruct { x: Self::other() }
I can't tell you the exact design decision, why Self functions are not imported automatically, but you can "work-around" this, by using the correct path.
Jumping to Visual Studio 2015 from Visual Studio 2013, I've noticed some differences in how static self-instances in managed C++ classes are accepted by the compiler. Consider these two examples:
Method 1:
public ref class CResourceManager
{
public:
static property CResourceManager^ Instance
{
CResourceManager^ get() { return %m_Instance; }
}
private:
static CResourceManager m_Instance;
};
Method 2:
public ref class CResourceManager
{
public:
static property CResourceManager^ Instance
{
CResourceManager^ get() { return m_Instance; }
}
private:
static CResourceManager^ m_Instance = gcnew CResourceManager;
};
Method 1 used to work on 2013, but it's failing to compile on 2015. I unfortunately do not have the exact compiler error handy, but it was one of those "Missing semicolon before variable name" errors, basically saying it couldn't find the type CResourceManager (pointing to the static variable declaration).
So on to my questions:
Is method 1 supposed to work or be valid in managed C++?
Why would the second method work in 2015, but not the first (i.e. what are the differences)?
Which method is the proper way to accomplish the end goal?
Method 2 is the proper way to do it. The code you have listed is the equivalent of the C# idiom.
Method 1 is a bit unusual.
The lack of a ^ on a declaration would normally mean that the variable is not allocated on the managed heap. However, since it's a static class member, I'm not sure where it actually gets created.
% is normally used for declaring tracking references, the equivalent of passing a variable by ref or out in C#. To be honest, I didn't think that applying % to a variable without either ^ or % and taking the result as a ^ was even valid. (Though considering the 2015 compiler rejects it, it may not be.)
Even if Method 1 is valid, I'd still go with Method 2: The storage location of m_Instance and how it's returned are both plain, common, and easy to understand. This beats having to think about how the code works any day.
I have a method in my native dll, that I want to use. The method returns an object of a type that is also in my native dll.I am trying to write a c++/CLI wrapper.
Now,
Can I get a return value as the object using C++/CLI and how do I do that?
Can we store and pass the native C++ object?
Should I need to create my own class resembling the native C++ class?
How would I marshal a class?
For Example,My native dll has these classes,
class X
{
/* some props and methods. */
};
Class Y
{
X* someMethod();
};
I need to wrap the someMethod class using C++/CLI. Will I be able to get the return value in the CLI?
Returning pointers to C++ objects from an exported function in a DLL is a pretty bad idea. It is a nasty memory management problem, you'd expect the client code to release the object. That can only come to a good end when both DLLs use the exact same version of the DLL version of the CRT (/MD compile option). If you can't recompile the native DLL then stop right now, you cannot make it work reliably or you'll have a big maintenance problem in the future.
Anyhoo, you need a wrapper for both classes. They should resemble this:
#pragma managed(push, off)
#include "xandy.h"
#pragma managed(pop)
using namespace System;
namespace something {
public ref class XWrapper {
X* mX;
public:
XWrapper(X* obj) : mX(obj) {}
~XWrapper() { this->!XWrapper(); }
!XWrapper() {
// Trouble is here!!!
delete mX;
}
};
public ref class YWrapper {
Y* mY;
public:
YWrapper() { mY = new Y; }
~YWrapper() { this->!YWrapper(); }
!YWrapper() { delete mY; }
XWrapper^ someMethod() {
return gcnew XWrapper(mY->someMethod());
}
};
}
Compiling in XCode 3.1.3 using GCC 4, under Leopard 10.5.8, with 10.5 as my target...
I have an interface, thus:
#interface testThing : NSObject { classContaininghooHa *ttv; }
#end
And an implementation, thus:
#implementation: testThing
- (void) instanceMethodMine
{
[ttv hooHa]; // works perfectly, compiles, links, hooHa is invoked.
}
// void cFunctionMine()
// {
// [ttv hooHa]; // compiler: 'ttv' undeclared (first use in this function) "
// }
void stupidCFunctionMine((testThing *)whom) // whom is passed class 'self' when invoked
{
[whom instanceMethodMine]; // compiles, links, works. :/
}
#end
Now, my understanding -- clearly flawed -- was that if you declared a variable, class ID or otherwise, it was private to the class, but within the class, is performed essentially as a global, stored in the allocated class instance for the duration of its existence.
That's how it acts for objc methods.
But in the c function above, also written within the class, the variable appears to be invisible. The doesn't make sense to me, but there it is.
Can someone explain to me what is going on?
While you're at it, how can I declare this as an instance variable so I can use the method within a c function declared within the class scope as shown above, as well as within methods?
Insight much appreciated.
It doesn't make any difference where you are declaring/defining your "normal" c functions. They are not part of the class, they are just plain old c functions. No connection to the class whatsoever. Passing the instance they work on is a workaround if you really don't want to make this function a true objective-c method.
interface methods have full access to it's member variables. And the C function is not part of the class and so it cannot access any class variables unless it takes an class instance as the argument.
void cFunctionMine()
{
[ttv hooHa]; // compiler: 'ttv' undeclared (first use in this function)
}
Clearly cFunctionMine is not part of the interface. So it does not what ttv is to send the message hooHa.
While you're at it, how can I declare this as an instance variable so I can use the method within a c function declared within the class scope as shown above, as well as within methods?
void cFunctionMine()
{
// 1. Create an instance using alloc and init
testThing *ttv = [ [testThing alloc] init ] ;
[ttv hooHa] ;
// Now the above statement is valid. We have a valid instance to which
// message can be passed to.
// .....
[ ttv release ] ;
// release the resources once you are done to prevent memory leaks.
}