I'm doing CLR wrapper. It builds successfully. Problem is that when I reference wrapper .dll in c# project RegisterMessageCallback method is totally absent. Here is what I see in metadata:
public class ATFeedWrapper : IDisposable
{
public ATFeedWrapper();
public sealed override void Dispose();
public void Login();
protected virtual void Dispose(bool A_0);
}
And here is wrapper class .h:
public ref class ATFeedWrapper
{
public:
ATFeedWrapper();
void Login();
void RegisterMessageCallback(void(*clbck)(string));
~ATFeedWrapper();
private:
ATFeedClient* client;
};
and .cpp:
ATFeedWrapper::ATFeedWrapper()
{
client = new ATFeedClient();
}
void ATFeedWrapper::Login()
{
client->Login();
}
void ATFeedWrapper::RegisterMessageCallback(void(*clbck)(string))
{
client->RegisterMessageCallback(*clbck);
}
ATFeedWrapper::~ATFeedWrapper()
{
delete client;
}
What's going on? Why is it missing?
Related
Currently I have made a design where my BaseClass is the guideline of how my program has to behave. I have made an abstract method DoWork() , the inheritors have to implement this method.
The thing is Class C overrides Setup() so it doesn't need DoWork() anymore. Now I am left with a throw new NotImplementedException();
Question: Is there a way how to improve my design so I won't have those methods with NotImplementedException?
public abstract class BaseClass
{
public virtual void Setup()
{
DoWork();
FinnishWork();
Environment.Exit(0);
}
public abstract void DoWork();
public abstract void FinnishWork();
}
public class A : BaseClass
{
public override void DoWork()
{
Console.WriteLine('A');
}
public override void FinnishWork()
{
Console.WriteLine('FinnishA');
}
}
public class B : BaseClass
{
public override void DoWork()
{
Console.WriteLine('B');
}
public override void FinnishWork()
{
Console.WriteLine('FinnishB');
}
}
public class C : BaseClass
{
public override void Setup()
{
FinnishWork();
Console.WriteLine('C');
}
public override void DoWork()
{
throw new NotImplementedException();
}
public override void FinnishWork()
{
Console.WriteLine('FinnishC');
}
}
As class C doesn't implement DoWork() it shouldn't really inherit from your abstract class.
You can only inherit from one class, but you can implement many interfaces.
In many ways it is simpler to deal with interfaces than abstract classes. Base classes, whether abstract or not really come into their own if they perform some function that you may wish to provide to you inheriting classes. An abstract class with empty methods isn't any better than an interface.
Consider something like:
public interface IDoWork
{
void DoWork();
}
public interface IBase
{
void Setup();
void FinnishWork();
}
public abstract class BaseClass : IBase, IDoWork
{
public virtual void Setup()
{
DoWork();
FinnishWork();
Environment.Exit(0);
}
public abstract void FinnishWork();
public abstract void DoWork();
}
public class A : BaseClass
{
public override void DoWork()
{
Console.WriteLine('A');
}
public override void FinnishWork()
{
Console.WriteLine("FinnishA");
}
}
public class B : BaseClass
{
public override void DoWork()
{
Console.WriteLine('B');
}
public override void FinnishWork()
{
Console.WriteLine("FinnishB");
}
}
public class C : IBase
{
public void Setup()
{
FinnishWork();
Console.WriteLine('C');
}
public void FinnishWork()
{
Console.WriteLine("FinnishC");
}
}
Examples in use:
IBase instanceA = new A();
BaseClass instanceB = new B();
IBase instanceC = new C();
instanceA.Setup();
instanceB.Setup();
instanceC.Setup();
instanceB.DoWork();
You're inheriting in too few steps. You need BaseClassLite and BaseClassHeavy to make this work.
Start with this:
public abstract class BaseClassLite
{
public virtual void Setup()
{
FinnishWork();
Environment.Exit(0);
}
public abstract void FinnishWork();
}
public abstract class BaseClassHeavy : BaseClassLite
{
public override void Setup()
{
DoWork();
base.Setup();
}
public abstract void DoWork();
}
(Or give them more meaningful names.)
Then you implement your classes like this:
public class A : BaseClassHeavy
{
public override void DoWork()
{
Console.WriteLine("A");
}
public override void FinnishWork()
{
Console.WriteLine("FinnishA");
}
}
public class B : BaseClassHeavy
{
public override void DoWork()
{
Console.WriteLine("B");
}
public override void FinnishWork()
{
Console.WriteLine("FinnishB");
}
}
public class C : BaseClassLite
{
public override void Setup()
{
base.Setup();
Console.WriteLine("C");
}
public override void FinnishWork()
{
Console.WriteLine("FinnishC");
}
}
The idea to have a Setup method in BaseClass while having 2 abstracts methods to implement is good (it is even given a name: template method pattern).
However there is one problem lying in how Setup() is declared in BaseClass: you made it virtual which goes against the principle that you want to enforce:
BaseClass is the guideline of how my program has to behave
It is now possible to override it (like you did in C) and break the behavior you want to enforce.
First, remove virtual in BaseClass then override DoWork in C as follow:
public override void DoWork() { }
Having this kind of empty method is a sign of a flawed abstraction (does C really need to inherit from BaseClass ?) but I can't help more if you don't provide more context about the real meaning and names of these classes/methods.
Use a second base class to be inherited from class C:
public abstract class BaseBaseClass
{
public virtual void Setup()
{
FinnishWork();
Environment.Exit(0);
}
...
}
public abstract class BaseClass : BaseBaseClass
{
public abstract void DoWork();
...
}
public class C : BaseBaseClass {...}
Given the following classes structure, is there a way to prevent BaseMethod() from being called or seen from FinalClass?
public abstract class BaseClass
{
protected virtual void BaseMethod()
{
}
}
public class IntermediateClass : BaseClass
{
protected sealed override void BaseMethod()
{
base.BaseMethod();
}
private void IntermediateMethod()
{
BaseMethod();
}
}
public class FinalClass : IntermediateClass
{
protected void FinalMethod()
{
}
}
You could make BaseMethod internal and place FinalClass in a different assembly to BaseClass and IntermediateClass.
I look at the definition of the public abstract class AddInBase : EntryPoint in an Excel 2007 Add-In project. This class is included in the project by default so I have no control over this class.
The interface
`
public interface EntryPoint
{
void BeginInit();
void EndInit();
void FinishInitialization();
void Initialize();
void InitializeDataBindings();
void OnShutdown();
void OnStartup();
}
contains only public methods.
But the realization of AddInBase includes protected virtual implementation of the OnShutdown() method:
public abstract class AddInBase : IAddInExtension, IExtension, EntryPoint, ISupportInitialize, IBindableComponent, IComponent, IDisposable
{
///
protected virtual void OnShutdown();
protected virtual void OnStartup();
///
}
How this can be?
Thanks for any clarification!
You have to explicitly implement the EntryPoint interface, since You are already using a protected method, the class AddInBase must satisfy the contract EntryPoint hence those are implemented explicitly
Example :
public interface EntryPoint
{
void BeginInit();
void EndInit();
void FinishInitialization();
void Initialize();
void InitializeDataBindings();
void OnShutdown();
void OnStartup();
}
public abstract class AddInBase : EntryPoint
{
void EntryPoint.OnShutdown()
{
OnShutdown();
}
void EntryPoint.OnStartup()
{
OnStartup();
}
protected virtual void OnShutdown()
{
throw new NotImplementedException();
}
protected virtual void OnStartup()
{
throw new NotImplementedException();
}
}
I'm learning DirectX but I don't know C++ very well so I decided to use SharpDX instead. But I'm stuck on this part in C++ they use the address of a function in the TypedEventHandler, but I don't know how to write that in C#? Can anyone help?
ref class App sealed : public IFrameworkView
{
public:
virtual void Initialize(CoreApplicationView^ AppView)
{
AppView->Activated += ref new TypedEventHandler
<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
}
virtual void SetWindow(CoreWindow^ Window) {}
virtual void Load(String^ EntryPoint) {}
virtual void Run() {}
virtual void Uninitialize() {}
void OnActivated(CoreApplicationView^ CoreAppView, IActivatedEventArgs^ Args)
{
CoreWindow^ Window = CoreWindow::GetForCurrentThread();
Window->Activate();
}
};
My conversion so far
internal class App : IFrameworkView
{
public void Initialize(CoreApplicationView AppView)
{
// Call OnActivated() when the Activated event is triggered
AppView.Activated += new TypedEventHandler<CoreApplicationView, IActivatedEventArgs>(this,this.OnActivated);
}
public void SetWindow(CoreWindow Window) {}
public void Load(String EntryPoint) {}
public void Run() {}
public void Uninitialize() {}
public void OnActivated(CoreApplicationView CoreAppView, IActivatedEventArgs Args)
{
CoreWindow Window = CoreWindow.GetForCurrentThread();
Window.Activate();
}
}
You don't need the "this" argument for the C# event wireup:
public sealed class App : IFrameworkView
{
public virtual void Initialize(CoreApplicationView AppView)
{
AppView.Activated += new TypedEventHandler <CoreApplicationView, IActivatedEventArgs>(OnActivated);
}
public virtual void SetWindow(CoreWindow Window)
{
}
public virtual void Load(string EntryPoint)
{
}
public virtual void Run()
{
}
public virtual void Uninitialize()
{
}
public void OnActivated(CoreApplicationView CoreAppView, IActivatedEventArgs Args)
{
CoreWindow Window = CoreWindow.GetForCurrentThread();
Window.Activate();
}
}
I am using Prism 4 and MEF for a WPF project. I have some DLL that needs to be loaded from a directory. These DLL implements IModule through IGame and are properly formed (or at least I think so) :
[Module(ModuleName = "SnakeModule")]
class SnakeModule : IGame
{
public void Initialize()
{
Console.WriteLine("test");
}
public void StartGame()
{
throw new NotImplementedException();
}
}
Currently, the main project is compiling but the module doesn't get initialized. I have trouble understanding how to setup my bootstrapper and the documentation isn't helping much since it doesn't have full example with a DirectoryModuleCatalog. The modularity quickstart isn't compiling either. Here is my bootstrapper :
class BootStrap : MefBootstrapper
{
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow = (Window)this.Shell;
Application.Current.MainWindow.Show();
}
protected override void ConfigureAggregateCatalog()
{
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(BootStrap).Assembly));
}
protected override IModuleCatalog CreateModuleCatalog()
{
DirectoryModuleCatalog catalog = new DirectoryModuleCatalog() { ModulePath = #"..\..\..\GameTestLib\bin\Debug" };
return catalog;
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
}
}
Paths for the DLLs are correct. To sum up, my question is : How should I setup my bootstrapper ?
First, and since you're using Prism, I suggest that you go with ModuleExport, as follows :
[ModuleExport("SnakeModule", typeof(IGame))]
But your problems actually comes from the fact you didn't set your class as a public one, therefore preventing the discovery of your module. So you need to change your code to this :
[ModuleExport("SnakeModule", typeof(IGame))]
public class SnakeModule : IGame
{
public void Initialize()
{
Console.WriteLine("test");
}
public void StartGame()
{
throw new NotImplementedException();
}
}
And it should be fine !