Shared pointer polymorphic object's reference not being passed properly - oop

I have a program whose main calls Simulation class object in the following manner.
int number_of_sims = std::stoi(num_sims)/MAX_THREADS_SIM_THREADS;
for (int inst=0; inst<Instruments.size(); inst++)
{
Simulation Simulations(Instruments[inst], Symbols[inst], number_of_sims);
SimVector.push_back(Simulations);
}
The simulation class in turn makes call to class Analysis and class Strategy and has the following skeleton.
class Simulation
{
public:
Simulation();
Simulation(Instrument& instrument, String& Symbol, int runs);
virtual ~Simulation();
boost::shared_ptr<Strategy> getStrategyName(String& StratName);
bool constructTimeSeries();
bool InitializeStrategy();
bool getMeanMTM();
bool printStrategyTrades(int run);
bool printAggregateMTM();
bool Run();
private:
String Symbol_;
double Mean_;
int runs_;
Instrument instrument_;
std::map<String, DoubleVector> AggregateMTM_;
boost::shared_ptr<Analysis> analysis_;
boost::shared_ptr<Strategy> strategy_;
};
The constructor looks something like this.
Simulation::Simulation(Instrument& instrument, String& Symbol, int runs)
: instrument_(instrument), Symbol_(Symbol), analysis_(new Analysis(instrument)), runs_(runs)
{
String filelocation = "/else/abc/xyz/klmn/file.config";
ConfigReader Config(filelocation, "=", false);
Config.parseFile();
String StrategyName = Config.getValue("strategyname");
Logger::getLogger().log(DEBUG, "The Strategy name is: " + StrategyName);
strategy_ = getStrategyName(StrategyName);
}
Now i make a polymorphic call to the XYZ strategy in the config file as below.
boost::shared_ptr<Strategy> Simulation::getStrategyName(String& StratName)
{
if (StratName.compare("XYZ") == 0)
return (boost::shared_ptr<Strategy>(new XYZ(instrument_, Symbol_)));
}
My XYZ strategy class inherits the strategy base and populates the TS_(LongStruct vector) member variable which is a protected member of class Strategy and uses it to perform certain funtions, one of which is getting the size of the vector.
The skeleton of these two classes looks something like below.
class Strategy
{
public:
Strategy(Instrument& instrument, String& Symbol);
virtual ~Strategy();
virtual bool Initialize();
virtual bool printData(std::ofstream& outputfile);
virtual double getMeanMTM();
protected:
virtual int CalculateTradeSignal(double& lower_limit, double& upper_limit, double& tau, double& meanTau, bool trade);
virtual double CalculateMTM(double& EntryPrice, double& ExitPrice);
std::map<int, String> Side_;
std::vector<String> TradeVector_;
Instrument instrument_;
LongToSymbolInfoPairVector TS_;
String Symbol_, start_, end_, tradeend_;
int numticks_, tradeticks_, tickinterval_;
double MeanMTM_;
};
XYZ:
class XYZ : public Strategy
{
public:
XYZ(Instrument& instrument, String& Symbol);
virtual ~XYZ();
bool Calculate();
bool CalculateTau();
bool Initialize();
bool updateNetPosition(int SigVal, int i, double& tau);
double getMeanMTM();
bool printData(std::ofstream& outputfile);
private:
// Initializers
bool entry_, trade_;
int netposition_;
long unsigned int tauMA_, lokBK_;
long entryT_, exitT_;
// TODO: Move the temporary variables, entryP, exitP, MTM to local variables
double entryP_, exitP_, MTM_, stoploss_, takeprofit_;
double lowtau_, hightau_;
LongVector entrytimeVector_, exittimeVector_;
IntVector posVector_;
DoubleVector entryPriceVector_, exitPriceVector_, MTMVector_, tauVector_;
};
In the CalculateTau function i try to get the size of the TS_ vector which has been initialized in the following manner.
bool XYZ::CalculateTau()
{
Logger::getLogger().log(DEBUG, "Calculating Tau .. ");
Logger::getLogger().log(DEBUG, "The size of the TS is: " + std::to_string(TS_.size()));
return true;
}
Strategy::Strategy(Instrument& instrument, String& Symbol)
: instrument_(instrument)
{
}
bool Strategy::Initialize()
{
TS_ = instrument_.GetTS();
return true;
}
Here get TS does the following:
class Instrument
{
public:
Instrument();
virtual ~Instrument();
LongToSymbolInfoPairVector GetTS() { return newTS_; }
private:
LongToSymbolInfoPairVector TS_, newTS_;
};
Now the problem is that i am getting the value of this size as 0.
Kindly assist in letting me know, where am i going wrong here.

I have been able to get around this problem by reducing the indirection from Simulation->Analysis->Instrument to Instrument->Simulation->Analysis then Analysis->Strategy

Related

How to change values of variables using methods?

I am having troubles incrementing the value of my instance variables. I tried making a method so that for every pet I buy, it will add that much to how many I already have. But when I print dogs variable, it says 0 even though I added 2. I'd appreciate any help. Thanks!
public class myStuff
static int dogs;
static int cats;
public static void main(String[] args) {
myStuff.buy(dogs, 2);
System.out.println(dogs);
}
public static void buy(int pet, int howMany) {
pet = pet + howMany;
}
}
you cant do that in java, since it is pass-by-value
In Java, method parameters are passed by value (which means the value of dogsin your case is passed in the first Place, but never touched). Objects however, are manipulated by reference. So, if you want to increase the number of pets, you could use a class Pet with a value count
public class Pet {
private int count;
public Pet(int count) {
this.count = count;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
If you then pass an instance of Pet to your buy function and increase the count via setCount, the value will be saved.

How to marshal this nested, and Pointer Used C structure in C#

typedef struct pt_input_bir
{
PT_BYTE byForm;
union {
PT_BIR *pBIR; ///< Used when byForm = PT_FULLBIR_INPUT */
PT_LONG lSlotNr; ///< Used when byForm = PT_SLOT_INPUT */
PT_BYTE abyReserved[20]; /** For future use */
} InputBIR;
} PT_INPUT_BIR
typedef struct pt_bir {
PT_BIR_HEADER Header;
PT_BYTE Data[1];
} PT_BIR
typedef struct pt_bir_header {
PT_DWORD Length;
PT_BYTE HeaderVersion;
PT_BYTE Type;
PT_WORD FormatOwner;
PT_WORD FormatID;
PT_CHAR Quality;
PT_BYTE Purpose;
PT_DWORD FactorsMask;
} PT_BIR_HEADER
and the C function is
PT_STATUS StoreFinger (
IN PT_CONNECTION hConnection,
IN PT_INPUT_BIR *pTemplate,
OUT PT_LONG *plSlotNr
)
Now I need to do the wrapper for the above C function in C#.
How should I marshal the PT_INPUT_BIR* structure and how should I unmarshal it after return of this function?
Please help me to solve this.
/********************** FOR MORE DETAIL ABOUT THIS QUESTION**************************/
C struct and function are defined in above. pls refer there.
C# Struct :
For C# struct declaration i have maintatined two struct for the one C struct. bcz one is for setting the values and another one id for passing to c function.
C# app struct:
[StructLayout(LayoutKind.Sequential)]//for app
public struct FPINPUTBIR
{
public byte byForm;
public InputBIRType InputBIR;
}
[StructLayout(LayoutKind.Sequential)] // here when i use explicit it throws exception so i removed it.
public struct InputBIRType
{
// [FieldOffset(0)]
public FPBIR pBIR;
//[FieldOffset(0)]
public int lSlotNr;
//[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] abyReserved;
}
C# wrapper struct:
[StructLayout(LayoutKind.Sequential)]
public struct FP_INPUTBIR
{
public byte byForm;
public IntPtr mIPBIR;
}
[StructLayout(LayoutKind.Explicit, Size = 20, CharSet = CharSet.Ansi)]
public struct Input_BIRType
{
[FieldOffset(0)]
public IntPtr mBIR;
[FieldOffset(0)]
public int lSlotNr;
//[FieldOffset(8)]
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
//public byte[] abyReserved;
}
finally i will copy the value from the C# app struct to wrapper struct before the call the C fun()
2a) C# App Side Code is :
//here mAppMemory is already known value
FPINPUTBIR lfipdata = new FPINPUTBIR();
FPDATA lfpdata = new FPDATA();
lfipdata.byForm = (byte)eFPVerifyBy.FULLBIR_INPUT;
lfipdata.InputBIR = new InputBIRType();
lfipdata.InputBIR.abyReserved = new byte[20];
lfipdata.InputBIR.pBIR.Data = new byte[mAppMemory[listBox2.SelectedIndex].Header.Length];
Array.Copy(mAppMemory[listBox2.SelectedIndex].Data, lfipdata.InputBIR.pBIR.Data, mAppMemory[listBox2.SelectedIndex].Header.Length);
lfipdata.InputBIR.pBIR.Header = mAppMemory[listBox2.SelectedIndex].Header;
Verify(ref lfipdata); //calling from C# APP side to C# wrapper
C# wrapper side:
public int Verify(ref FPINPUTBIR apStoredTemplate )
{
// i passed the args (apStoredTemplate ) but throws exception struct mismatch with C struct.
//here i don't know what should i do.
CDLL.StoreFinger(..,ref apStoredTemplate,.. ); //pls refer the C function above
}
Questions:
Do i really need two C# structures for this.
what should i do inside the C# wrapper function. please remeber i have two C# struct with diff members.
Thanks.
You just need a little extension on what you used in the previous question for PT_BIR. There we marshalled that variable length struct as byte[]. You can use the same code to generate the byte array, and I won't revisit that.
Next you need the union. That is:
[StructLayout(LayoutKind.Explicit, Size = 20)]
public struct PT_INPUT_BIR_UNION
{
[FieldOffset(0)]
public IntPtr pBIR;
[FieldOffset(0)]
public int lSlotNr; // I'm guessing what PT_LONG is
}
No need to declare the reserved part of the union. The size takes care of that.
Then PT_INPUT_BIR is
[StructLayout(LayoutKind.Sequential)]
public struct PT_INPUT_BIR
{
Byte byForm;
PT_INPUT_BIR_UNION InputBirUnion;
}
Then you need to use GCHandle to pin the PT_BIR byte array. Let's keep to the same naming as used at that question, and assume that the PT_BIR is held in a byte[] variable named data.
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
PT_INPUT_BIR inputBir;
inputBir.byForm := ...;
inputBir.InputBirUnion.pBIR = handle.AddrOfPinnedObject();
// now call StoreFinger passing ref inputBir
}
finally
{
handle.Free();
}
When you declare StoreFinger the PT_BIR* parameter should be declared as ref PT_BIR.

Pass an argument to task in C++/CLI?

I have this code for the C# in Visual Studio 2012.
public Task SwitchLaserAsync(bool on)
{
return Task.Run(new Action(() => SwitchLaser(on)));
}
This will execute SwitchLaser method (public nonstatic member of a class MyClass) as a task with argument bool on.
I would like to do something similar in managed C++/CLI. But I am not able to find out any way how to run a task, which will execute a member method taking one parameter.
Current solution is like this:
Task^ MyClass::SwitchLaserAsync( bool on )
{
laserOn = on; //member bool
return Task::Run(gcnew Action(this, &MyClass::SwitchLaserHelper));
}
Implementation of SwitchLaserHelper function:
void MyClass::SwitchLaserHelper()
{
SwitchLaser(laserOn);
}
There must be some solution like in C# and not to create helper functions and members (this is not threadsafe).
There isn't yet any way to do this.
In C# you have a closure. When your C++/CLI compiler was written, the standardized syntax for closures in C++ was still being discussed. Thankfully, Microsoft chose to wait and use the standard lambda syntax instead of introducing yet another unique syntax. Unfortunately, it means the feature isn't yet available. When it is, it will look something like:
gcnew Action([this, on](){ SwitchLaser(on) });
The current threadsafe solution is to do what the C# compiler does -- put the helper function and data members not into the current class, but into a nested subtype. Of course you'll need to save the this pointer in addition to your local variable.
ref class MyClass::SwitchLaserHelper
{
bool laserOn;
MyClass^ owner;
public:
SwitchLaserHelper(MyClass^ realThis, bool on) : owner(realThis), laserOn(on) {}
void DoIt() { owner->SwitchLaser(laserOn); }
};
Task^ MyClass::SwitchLaserAsync( bool on )
{
return Task::Run(gcnew Action(gcnew SwitchLaserHelper(this, on), &MyClass::SwitchLaserHelper::DoIt));
}
The C++ lamdba syntax will simply create that helper class for you (currently it works for native lambdas, but not yet for managed ones).
Here's generic code I wrote this afternoon which might help (although it's not an exact match for this question). Maybe this will help the next person who stumbles onto this question.
generic<typename T, typename TResult>
ref class Bind1
{
initonly T arg;
Func<T, TResult>^ const f;
TResult _() { return f(arg); }
public:
initonly Func<TResult>^ binder;
Bind1(Func<T, TResult>^ f, T arg) : f(f), arg(arg) {
binder = gcnew Func<TResult>(this, &Bind1::_);
}
};
ref class Binder abstract sealed // static
{
public:
generic<typename T, typename TResult>
static Func<TResult>^ Create(Func<T, TResult>^ f, T arg) {
return (gcnew Bind1<T, TResult>(f, arg))->binder;
}
};
Usage is
const auto f = gcnew Func<T, TResult>(this, &MyClass::MyMethod);
return Task::Run(Binder::Create(f, arg));
Here's the working answer.. Have tested it.. Passing an argument (int) to the action sampleFunction.
#include "stdafx.h"
#include "CLRSamples.h"
using namespace System;
using namespace System::Threading;
using namespace System::Threading::Tasks;
using namespace System::Collections;
using namespace System::Collections::Generic;
void CLRSamples::sampleFunction(Object^ number)
{
Console::WriteLine(number->ToString());
Thread::Sleep((int)number * 100);
}
void CLRSamples::testTasks()
{
List<Task^>^ tasks = gcnew List<Task^>();
for (int i = 0; i < 10; i++)
{
tasks->Add(Task::Factory->StartNew((Action<Object^>^)(gcnew Action<Object^>(this, &CLRSamples::sampleFunction)), i));
}
Task::WaitAll(tasks->ToArray());
Console::WriteLine("Completed...");
}
int main(array<System::String ^> ^args)
{
CLRSamples^ samples = gcnew CLRSamples();
samples->testTasks();
Console::Read();
return 0;
}
I had a similar problem when I wanted to provide a parameter to a task executing a method which does not return a value (retuns void). Because of that Func<T, TResult> was not an option I could use. For more information, please check the page Using void return types with new Func.
So I ended up with a solution where I created a helper class
template <typename T>
ref class ActionArguments
{
public:
ActionArguments(Action<T>^ func, T args) : m_func(func), m_args(args) {};
void operator()() { m_func(m_args); };
private:
Action<T>^ m_func;
T m_args;
};
which is using Action<T> delegate to encapsulate a method that has a single parameter and does not return a value.
I would then use this helper class in a following way
ref class DisplayActivationController
{
public:
DisplayActivationController();
void StatusChanged(EventArgs^ args) { };
}
Action<EventArgs^>^ action =
gcnew Action<EventArgs^>(this, &DisplayActivationController::StatusChanged);
ActionArguments<EventArgs^>^ action_args =
gcnew ActionArguments<EventArgs^>(action, args);
Threading::Tasks::Task::Factory->
StartNew(gcnew Action(action_args, &ActionArguments<EventArgs^>::operator()));
Approach using the helper class is probably not the most elegant solution, but is the best one I could find to be used in C++/CLI which does not support lambda expressions.
If you are using c++/ CLR, then make a C# dll and add reference to it
namespace TaskClrHelper
{
public static class TaskHelper
{
public static Task<TResult> StartNew<T1, TResult>(
Func<T1, TResult> func,
T1 arg)
=> Task.Factory.StartNew(() => func(arg));
public static Task<TResult> StartNew<T1, T2, TResult>(
Func<T1, T2, TResult> func,
T1 arg1, T2 arg2)
=> Task.Factory.StartNew(() => func(arg1, arg2));
}
}
bool Device::Stop(int timeout)
{
_ResetEvent_Running->Set();
return _ResetEvent_Disconnect->WaitOne(timeout);
}
Task<bool>^ Device::StopAsync(int timeout)
{
auto func = gcnew Func<int, bool>(this, &Device::Stop);
return TaskClrHelper::TaskHelper::StartNew<int,bool>(func,timeout);
}

Unrecognized selector: [NSSQLToMany _setInverseManyToMany:]

This is the strangest error I've ever had, simply because I can't find any information on it anywhere.
Background:
I have an app using RestKit (current master) that maps to Core Data. I'm using a custom mapping provider (subclass of RKObjectMappingProvider). This generates all of the mappings that I need, similar to the RKGithub project.
Some of my objects have many-to-many relationships, so I have to register some of the relationships (in the mapping provider) after the others are set up to avoid an infinite recursion. (Friends has_many Friends has_many Friends...)
When the app runs and RestKit configures itself, an error occurs on this line (in RKManagedObjectStore.m)
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_managedObjectModel];
I can't step into the "initWithManagedObjectModel:" method. The only information I get is this exception in the logs:
-[NSSQLToMany _setInverseManyToMany:]: unrecognized selector sent to instance 0xcc78890
I have no idea what caused this or how to fix it. I can't find any documentation on it or even anyone who's had this problem before. All I could find was this dump of the iOS framework:
public struct NSSQLManyToMany : IEquatable<NSSQLManyToMany> {
internal NObjective.RuntimeObject Handle;
public static readonly RuntimeClass ClassHandle = CoreDataCachedClasses.NSSQLManyToMany;
public static implicit operator IntPtr( NSSQLManyToMany value ) {
return value.Handle;
}
public static implicit operator NObjective.RuntimeObject( NSSQLManyToMany value ) {
return value.Handle;
}
public override bool Equals( object value ) {
var compareTo = value as NSSQLManyToMany?;
return compareTo != null && Handle == compareTo.Value.Handle;
}
public bool Equals( NSSQLManyToMany value ) {
return Handle == value.Handle;
}
public static bool operator ==( NSSQLManyToMany value1, NSSQLManyToMany value2 ) {
return value1.Handle == value2.Handle;
}
public static bool operator !=( NSSQLManyToMany value1, NSSQLManyToMany value2 ) {
return value1.Handle != value2.Handle;
}
public NSSQLManyToMany( IntPtr value ) {
this.Handle = new RuntimeObject( value );
}
public static NSSQLManyToMany alloc() {
return new NSSQLManyToMany( ClassHandle.InvokeIntPtr( Selectors.alloc ) );
}
unsafe public NObjective.RuntimeObject inverseColumnName() {
RuntimeObject ___occuredException;
var ___result = NativeMethods.inverseColumnName( Handle, CachedSelectors.inverseColumnName, out ___occuredException, 0 );
if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException );
return new NObjective.RuntimeObject( ___result );
}
unsafe public NObjective.RuntimeObject inverseManyToMany() {
RuntimeObject ___occuredException;
var ___result = NativeMethods.inverseManyToMany( Handle, CachedSelectors.inverseManyToMany, out ___occuredException, 0 );
if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException );
return new NObjective.RuntimeObject( ___result );
}
unsafe public bool isMaster() {
RuntimeObject ___occuredException;
var ___result = NativeMethods.isMaster( Handle, CachedSelectors.isMaster, out ___occuredException, 0 );
if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException );
return ___result;
}
unsafe public bool isReflexive() {
RuntimeObject ___occuredException;
var ___result = NativeMethods.isReflexive( Handle, CachedSelectors.isReflexive, out ___occuredException, 0 );
if( ___occuredException != RuntimeObject.Null ) throw RuntimeException.Create( ___occuredException );
return ___result;
}
private static class NativeMethods {
[DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
public static extern IntPtr inverseColumnName( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
[DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
public static extern IntPtr inverseManyToMany( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
[DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
public static extern bool isMaster( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
[DllImport(Runtime.InteropLibrary, EntryPoint = "objc_msgSend_eh2")]
public static extern bool isReflexive( RuntimeObject ___object, Selector ___selector, out RuntimeObject ___occuredException, int ___stackSize );
}
static internal class CachedSelectors {
public static readonly Selector inverseColumnName = "inverseColumnName";
public static readonly Selector inverseManyToMany = "inverseManyToMany";
public static readonly Selector isMaster = "isMaster";
public static readonly Selector isReflexive = "isReflexive";
}
}
Which very clearly seems to have a setter:
public NSSQLManyToMany( IntPtr value ) {
this.Handle = new RuntimeObject( value );
}
Any ideas?
EDIT:
I should add that I've tried all of the "simple" solutions. Deleting the app from the sim doesn't work.
I suspect that it might be because I have an entity that has two "has and belongs to many" relationships with the same (different) entity. But I can't see why that would be an actual problem.
Just figured this out!
I had two relationships on one entity pointing to another entity, and they inadvertently had the same inverse.
To illustrate:
Part:
has many (Car*)cars, inverse parts
has one (Car*)deliveryTruck, inverse parts
A bit contrived, but the idea is there. I had to change the second parts to some other property.
Hopefully this will help someone else with the same cryptic error message. You'd expect clang to warn you about something like this! (It freaks out enough as it is if you don't have an inverse at all).

converting System::String^ to std::string inside ref class member

I'm trying to write a wrapper for a very simple std::pair<std::string, float> in C++/CLI but I get the error message: no instance of constructor "std::pair<_Ty1, _Ty2>::pair [with _Ty1=std::string, _Ty2=float]" matches the argument list, argument types are: (std::string, float)
What am I doing wrong and why doesn't std::string match std::string?
#include <msclr\marshal_cppstd.h>
#include <string>
using namespace System;
using namespace System::Runtime::InteropServices;
typedef std::pair<std::string, float> Parameter;
static std::string StringToNative(String^ str)
{
msclr::interop::marshal_context context;
return context.marshal_as<std::string>(str);;
}
public ref class CLIParameter
{
public:
CLIParameter(System::String^ name, float value) : _name(name), _value(value) {};
Parameter toNativeParameter()
{
return Parameter(StringToNative(_name), _value);
}
private:
System::String^ _name;
float _value;
};
int main()
{
CLIParameter^ par = gcnew CLIParameter("test", 1);
}
Your method toNativeParameter() is incorrect. It should be defined as follows:
Parameter toNativeParameter()
{
// copy the floating point value from the managed heap to the local stack
float value = _value;
// create the pair
return std::make_pair(StringToNative(_name), value);
}
Notice that you should use std::make_pair to create the actual pair. In addition, a key step to make this work is copying the floating point value from the managed heap into the local stack. The reason is that native functions such as std::make_pair cannot create native references to an object from the managed (garbage collected) heap i.e. a member of a managed class.