Can't return array<int^, 2>^ c++/cli - c++-cli

I am trying to use this method:
array<int^,2>^ Function1()
{
return gcnew array<int^,2>{ { 1 }, { 2 }};
}
by typing:
auto x = Function1();
but I get an error:
Exception thrown at 0x73572A55 (clr.dll) in Project1.exe: 0xC0000005: Access violation writing location 0x00000834.
How to solve this problem if I want to keep the returning type?
Thanks!

int is not a reference type, and should not be used with ^.
If you remove the ^ from int^, this code does run:
array<int, 2>^ Function1()
{
return gcnew array<int, 2>{ { 1 }, { 2 } };
}

How to solve this problem if I want to keep the returning type?
This return type is improper. There's no way to represent int^ in C#, and probably not in other .Net languages either. Having a variable of type int^ is a performance hit for each access of the integer, and I believe it's more work for the garbage collector as well.
The proper fix is to change int^ to int everywhere.
Now, that said, I cannot reproduce the error you're getting. Perhaps your error is elsewhere.
array<int^,2>^ Function1()
{
return gcnew array<int^,2>{ { 1 }, { 2 }};
}
int main(array<System::String^>^ args)
{
auto x = Function1();
Debug::WriteLine(x[0,0]);
return 0;
}
Result:
1

Related

Is there any concern about returning generic type object in Dart?

I want to implement a different error handling approach in a project without chaining exceptions.
To make it simple as possible, I am tend to write my own basic either-like model.
class Either<F, T> {
final F failure;
final T value;
const Either(this.failure, this.value);
Object check (){
if (failure != null) return failure;
return value;
}
}
I am concerning about returning the type Object, is there any problem or considerations with that in Dart or any other language?
Edit:
or returning dynamic type...
dynamic check(){
if (failure != null) return failure;
return value;
}
I think in your case, it's kind of a wired implementation. The question is, what do you want to do with the actual implementation ? Do you want to replace an if else that will appear over and over? In that case, what would you do if you have to handle the error (failure) ? I think a better approach is to use functions as parameters. Here's a short suggestion.
class Either<T, F> {
T value;
F fail;
Either(this.value, this.fail);
void check(success(T value), {failure(F fail)}) {
if (fail != null && failure != null) {
failure(fail);
} else if (value != null) {
success(value);
}
}
}
class SomeClass {
void checkTheImplementation() {
Either<String, Error> maybeString = Either("testing", null);
// if you don't want to handle the error.
maybeString.check((value) => print(value));
// if you want to handle the error
maybeString.check((value) => print(value), failure: (err) {
print(err.toString());
});
}
}
I have looked over and decided to go with baihu92's either_type way. It's much more clear and comprehensible than either in the dartz package. Here is my implementation:
and the usage is like:

Failure failing in CATCH

I'm probably overlooking something simple, but I do not expect the below code to fail. It is behaving as if I wrote die instead of fail in the catch block.
The Failure does not get properly handled and the code dies.
sub foo()
{
try {
say 1 / 0;
CATCH { default { fail "FAIL" } }
}
return True;
}
with foo() {
say "done";
}
else
{
say "handled {.exception.message}"
}
Output:
FAIL
in block at d:\tmp\x.pl line 5
in any at d:\tmp\x.pl line 5
in sub foo at d:\tmp\x.pl line 4
in block <unit> at d:\tmp\x.pl line 11
To bring home to later readers the full force of what Yoda said in their comment, the simplest solution is to unlearn the notion that you have to try in order to CATCH. You don't:
sub foo()
{
say 1 / 0;
CATCH { default { fail "FAIL" } }
return True;
}
with foo() {
say "done";
}
else
{
say "handled {.exception.message}"
}
correctly displays:
handled FAIL
According to the Failure documentation this seems to be the defined behavior.
Sink (void) context causes a Failure to throw, i.e. turn into a normal exception. The use fatal pragma causes this to happen in all contexts within the pragma's scope. Inside try blocks, use fatal is automatically set, and you can disable it with no fatal.
You can try to use the no fatal pragma.
sub foo() {
try {
no fatal;
say 1 / 0;
CATCH { default { fail "FAIL" } }
}
}
unless foo() {
say "handled"
}

Immediate Access Violation when debugging Windows.Devices.Sensors project in Windows 7

I have a large solution with 50+ unmanaged projects in it. I have recently added a project with managed code in it to the solution. The managed code accesses Windows.Devices.Sensors in a .NET dll. This dll is eventually wrapped by unmanaged code and called from another unmanaged project.
My problem is that I get the following access violation before main() even executes.
Unhandled exception at 0x744b8ea0 in myApplication.exe: 0xC0000005: Access violation.
Managed code:
#using <Windows.winmd>
using namespace Windows::Devices::Sensors;
#include <math.h>
namespace TabletSensors
{
namespace NET
{
public ref class DotNetDllClass
{
public:
DotNetDllClass()
{
Initialization();
}
~DotNetDllClass()
{
}
float* GetQuaternion()
{
OrientationSensorReading^ reading = _orientation->GetCurrentReading();
if( reading != nullptr )
{
float* quat = new float[4];
quat[0] = reading->Quaternion->X;
quat[1] = reading->Quaternion->Y;
quat[2] = reading->Quaternion->Z;
quat[3] = reading->Quaternion->W;
return quat;
}
else
{
return NULL;
}
}
private:
void Initialization()
{
_orientation = OrientationSensor::GetDefault();
if( _orientation != nullptr )
{
_orientation->ReportInterval = 16;
}
else
{
// not good ... throw exception or something
}
}
OrientationSensor^ _orientation;
};
}
}
Wrapper header file:
namespace TabletSensors
{
namespace NETWrapper
{
class DLLEXPORT_SENSORS WrapperClass
{
public:
__stdcall WrapperClass();
__stdcall ~WrapperClass();
float* __stdcall GetQuaternion();
};
}
}
Wrapper cpp file:
#define MIXSENSORS_BUILD
#include <gcroot.h>
#include "DotNetWrapper.h"
#include "DotNetDll.h"
using namespace TabletSensors::NETWrapper;
using namespace TabletSensors::NET;
static gcroot<TabletSensors::NET::DotNetDllClass^> Sensors = nullptr;
static System::UInt16 refCount = 0;
#pragma managed
inline TabletSensors::NET::DotNetDllClass^ GetSensors(void)
{
return (TabletSensors::NET::DotNetDllClass^)Sensors;
}
void Init()
{
++refCount;
if(GetSensors() == nullptr)
{
Sensors = gcnew TabletSensors::NET::DotNetDllClass();
}
}
void CleanUp()
{
if( refCount > 0 )
{
--refCount;
}
}
float* GetQuaternion_()
{
return Sensors->GetQuaternion();
}
#pragma unmanaged
TabletSensors::NETWrapper::WrapperClass::WrapperClass()
{
Init();
}
TabletSensors::NETWrapper::WrapperClass::~WrapperClass()
{
CleanUp();
}
float* TabletSensors::NETWrapper::WrapperClass::GetQuaternion()
{
float* x = new float[4];
return GetQuaternion_();
}
#pragma managed
Unmanaged project referencing my wrapper class:
#include "DotNetWrapper.h"
.
.
.
void UnmanagedProject::Update()
{
// if this line is present, I get an access violation without hitting any breakpoints.
TabletSensors::NETWrapper::WrapperClass _tabletSensors;
.
.
.
}
Since the managed code is trying to access Tablet Sensors I understand why it doesn't work on my Windows 7 desktop. What I don't understand it why it won't even allow me to debug my code at all. No breakpoints are hit before the Access Violation occurs.
What I would really like to figure out is how to use exception handling or #ifdefs to keep this crash from happening. But I have had very little luck.
Any ideas?
The fix is to Delay Load the managed DLL. The allows the application to run until that DLL is explicitly called. Thanks to Ben Voight for his answer here: https://stackoverflow.com/a/28467701/1454861

Why does C++ CLI force classes to have variables in constructor method?

public ref class masterWeapon{
public :
property int Slot {
int get(){
return 0;
}
}
masterWeapon(){
}
};
OSamp::masterWeapon mw();
int v = mw.Slot; //ERROR error C2228: left of '.Slot' must have class/struct/union
However following code ran fine :
public ref class masterWeapon{
public :
property int Slot {
int get(){
return 0;
}
}
masterWeapon(int useless){
}
};
OSamp::masterWeapon mw(231312);
int v = mw.Slot; //works fine
Why does C++ CLI force classes to have variables in constructor method?
It doesn't, you just have an error in your code.
OSamp::masterWeapon mw();
The error message is slightly misleading; it is the line above that is causing the issue. The compiler is telling you that mw is not an instance of an object. mw is interpreted as a prototype for a function which takes no arguments and returns an OSamp::masterWeapon.
The line should be rewritten as:
OSamp::masterWeapon mw;

C++/CLI managed VS. unmanaged short

I have an unmanaged library which I want to use from a managed class. The interface of the function is:
GetProgress(short* value);
So I wrote in my managed class:
short val = 0;
GetProgress(&val);
I got the following error:
Error C2664: 'GetProgress' : cannot convert parameter 1 from 'cli::interior_ptr' in 'short *' with [ Type=short ]
I read this topic, so I changed my code into:
short val = 0;
pin_ptr<short*> pVal = &val;
GetProgress(pVal);
And in addition to the previous error I get
Error C2440: 'initialisation' : cannot convert from 'short *' to 'cli::pin_ptr' with [ Type=short * ]
How can I fix this?
That's an interesting one.
The following code produces C2664 because val can only be a managed type:
using namespace System;
void GetProgress(short* value)
{
// unmanaged goodness
}
ref class XYZ : System::Object
{
short val;
void foo()
{
GetProgress(&val);
}
};
but if you declare a local variable first, it all works fine...
using namespace System;
void GetProgress(short* value)
{
// unmanaged goodness
}
ref class XYZ : System::Object
{
short val;
void foo()
{
short x;
GetProgress(&x);
val = x;
}
};
Not exactly the answer you were looking for, but I thought I'd include it since it's a simple fix.