Using C# from C++.

As people might know I frequent Reddit, and StackOverflow, but mostly Reddit. I do this obviously for investing advice, but secondly to share programming thoughts and ideas. I think giving back to community is an important part of life, and of the things I have to offer, programming is my best.

There are a great deal of resources out there that outline how to call native libraries from C#. From P/Invoke, to tutorials on interoperating using C++/CLI. I’d hazard a guess this is because C# is of the top 8 (59.7%) of our beloved languages according to StackOverflows annual developer survey in 2020. Much to my dismay, C++ falls somewhere in the basement, with a measly 43.4% of developers who actually enjoy using the language. So if you’re a C# developer, and you’re interested in calling some black-box C++ library written by your ancestors (or our modern day C++ superstars!) you’ve got plenty of resources. However, if you’re a C++ dev, and you’re looking to add a bit of .NET to your life. You might have a hard time finding resources on how to go about it. Here’s my attempt to fill that void.

As a disclaimer, I’ll need you to know that this should be a last resort. You should research whether there are other options, like COM or a different native option. When we talk about C++, we think zero overhead abstraction, we think performance, we think light weight. What we’re doing isn’t any of that. When you use this technique, you’re pulling in the CLR into your application. So this is a sledgehammer solution, use it as such.

Calling C# libraries from C++ is actually easier than you’d think. C++/CLI is mostly used to go the reverse direction, and expose your native libraries into your managed. However, you can use it to expose managed code into C++. To be completely honest, I don’t know how this all works under the hood. I’d love if someone could share!

You can find the supplemental code for this here. To keep my wordiness to a minimum. I’ll just describe the setup in this post.

First create a C++/CLI project in Visual Studio. Then add your native class and export it.

// native_to_managed.h
#pragma once

#include <string>
#include <memory>

#ifdef DLL_EXPORT
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif

class DLL_API native_to_managed
{
public:
    native_to_managed();
    ~native_to_managed();
    void write_to_console(const std::string& message);

private:
    class impl;
    std::unique_ptr<impl> impl_;
};

You’ll notice here the use of the familiar pimpl pattern, or in other words a “compiler firewall”. This is necessary, because this .h will be included by our purely native project, and will need to have hidden the fact that it holds handles into the CLR. You’ll notice the minimal include dependencies. This is the purpose of the firewall. This interface will be purely C++. If you need to pass complex objects which are also managed, you’ll need to do the same for every object you want to export. You then implement the native_to_managed as per the pimpl pattern, and forward the calls into the impl.

// native_to_managed.cpp

#include "native_to_managed.h"
#include "native_to_managed.impl.h"

native_to_managed::native_to_managed()
    :impl_(std::make_unique<impl>())
{
}

// You need this in the compilation unit so it knows about the impl.
native_to_managed::~native_to_managed() = default;

void native_to_managed::write_to_console(const std::string &message)
{
    impl_->write_to_console(message);
}

You’ll notice that we’ve pulled the definition of the destructor into the .cpp file. You’ll need to do this, because inside this cpp is where the compiler gets an understanding of what the actual “impl” is, via the include of native_to_managed.impl.h. Otherwise, because we’re using std::unique_ptr we’ll get an error saying something about it not knowing how to delete. I’ve done this by doing =default which will use the compiler default generated destructor. I read somewhere that this is optimal over ~native_to_managed(){}, in what the compiler actually generates. Since then, I always opt for the =default option when I have default dtors. But most people don’t know you can do this in the .cpp, not just in the .h.

Inside the impl is where the magic happens. (do people still say that?)

//native_to_managed.impl.h
#pragma once
#include "native_to_managed.h"

#include <gcroot.h>
#include <msclr/marshal_cppstd.h>

using namespace dotnet_interop_net_lib;

class native_to_managed::impl
{
public:
    void write_to_console(const std::string &message)
    {
        managed_->WriteToConsole(msclr::interop::marshal_as<System::String ^>(message));
    }

private:
    gcroot<ManagedClass ^> managed_;
};

Technically, you can split the declaration and implementation up into a .h/.cpp. I’m just lazy, and chose to do them both in the .h. Follow your heart, or your company coding standards, or what your boss says to do, not what she does.

The most important thing to notice is the inclusion of the gcroot<T> a class that allows you to hang on to a Garbage Collector reference (handle) from your native class. You can see I’m holding on to a ManagedClass^ the hat represents in C++/CLI that this is reference to a GC object. You can use the gcroot to dereference and call into your managed class.

You’ll also notice that I’ve used msclr::interop::marshal_as<System::String ^> to translate from our unmanaged memory (std::string) to our managed memory (System.String), again note the hat. Depending on your situation, you’ll need to just understand your own marshalling requirements.

The last very important thing, is that your standard Visual Studio project referencing won’t work. If you were using C# and you referenced this project, the library would get copied to the project output. However, if you do the reverse, Visual Studio fails to setup the references. So you have to setup the additional library dependencies to point to the lib.

Edit: To clarify, this will be in the linker input of your native project.

Given this short setup — you’ll be able to call into a C#/Managed DLL. Remember, this is a sledgehammer so use it accordingly.

As always, Happy Coding!

I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail. Abraham Maslow

What I’ve learned from 2 years of Productivity Research and Application Development

Over the course of the last two years I’ve embarked on a journey developing a productivity (read to-do list) application. When I started out I dreamt of a productivity app that worked for me. Because I, like many others I can only assume, hadn’t gotten much value out of the many applications I had tried and failed to use in the past. I embarked on a journey to fulfil that dream by creating an application founded on organizational psychology principles proven to increase our ability to produce, and reduce the anxiety and stress related to our workloads. On January 1st, 2021 I went production live with a Beta version of my application Fuss.

The application is still in the Beta stage of its lifecycle, because I’ve found it challenging to find users, and get feedback from those users. So I’ve had to use myself, and my fiancĂ©e as guinea pigs of the application. I also have 2 or 3 other people who occasionally use the application and give feedback. Because /r/productivity prohibits self promotion, I wanted to take a step back from promoting my application, and focus this blog post on the productivity tips and tricks that I’ve learned in the past 2 years of research and development on my application.

Let’s first look at three definitions of “productivity”. The first, the Oxford dictionary definition of productivity.

productivity

noun
the rate at which a worker, a company or a country produces goods, and the amount produced, compared with how much time, work and money is needed to produce them — Oxford Dictionary

Wikipedia defines it as

Productivity describes various measures of the efficiency of production. — Wikipedia

And the well known James Clear, defines it

“Productivity is a measure of efficiency of a person completing a task. ” — James Clear, “The Productivity Guide”

In all of these definitions, the key takeaway is efficiency. The more efficient we can be at doing something, the more we can get done, and the less we expend getting it done. This means we get more done with less. A fantastic target to set our sights on. So how do we go about achieving efficiency in our everyday lives? And why do we even want to do that?

Well it might seem like a stupid question, but the answer for me is time. For a human being, time is a finite resource. It’s one of the only things in life money can’t buy, and you only get so much of it. I didn’t realize this until my mid-twenties that we only get so much time, so we must spend it wisely.

Our genetics and psychology directly impact our behaviour, and how we spend our time. Think about how your spend your time when you’re riding a high from some praise at work, vs. when you’ve just had a relationship end. Think about how your best friend does. This means that our individual productivity is unique to each person, and can be affected by life situation, health, and even diet. Your lifestyle directly impacts how you spend your time, and what you get done with the time you spend.

The good news is, that it’s not static. As your life evolves and changes, so does your ability to be productive. If you’re the type of person that feels like you have never ending projects, and that tasks take way longer than they should. You can change it. You just have to start. Here are three huge takeaways I learned while I was developing Fuss.

  1. Consistency is King.
  2. Get it out of your head, and prioritize it.
  3. Give yourself room to breath.

1. Consistency is King.

Regardless of what book you read, be it Good to Great, Atomic Habits, The Self-Discipline Blueprint, they all have talk about consistency. One of the biggest psychological issues that we face as humans, is how our ego impacts our ability to be consistent. The thing that truly productive people understand is that doing something is an investment, and doing it consistently has a compounding effect. Where many individuals would try something and have it be sub-standard and quit. The productive individual knows that the first time they do something is likely not going to be the best, but eventually it will be. This comes from an ability to silence the inner critic long enough to find the courage to try again. Some people genetically have a higher internal locus of control, meaning they can seemingly brew motivation from their insides. For some of us that doesn’t come naturally. Two things we can do to cultivate consistency, and muzzle that inner critic are

1. Get a reason why – whether this reason is that you want the pretty girl to notice you, or you want to prove it to your parent. The reason doesn’t really matter, other than that you need to connect with it. It can’t be because your parent or spouse told you to. You have to truly want it, and connect with that reason.

2. Celebrate the small wins. Have you ever noticed that in digital to-do lists when you complete a task, it’s gone forever? That feels great in that moment. The rush of dopamine you receive completing that task, feels great. But it’s fleeting. What happens when you haven’t completed a task in a while, or you’re stuck working on something for more than 10 minutes? How do you get that fix? You celebrate the small wins, by looking at what you’ve accomplished this far. You’ve come 80% of the way, it’s no time to sit on your laurels, but you need to at least pat yourself on the back for coming this far. It’s why paper and pencil to-do lists can be so satisfying. You can easily see what you’ve already done.

The way you cultivate discipline and consistency doesn’t matter, all that matters is that you do, and you earn that 1% compounding interest daily.

2. Get it out of your head, and prioritize it.

Human beings are fallible, it’s the beauty of being human, and it’s what makes us well human. We make mistakes, and we forget things, we forgive and we love. That’s what being human is about. This is also what allows us to be creative and structured. But being forgetful, as human as it is, impacts our time. When you forget to do something, you often have to rush to do it, or you have to accept that it didn’t get done. It’s an awful feeling realizing you’ve forgotten something. It’s often times paired with anxiety, and regret, and usually impacts future situations. Your mind knows this. So it does things to try and combat forgetfulness. Even if you have an eidetic memory you will still forget things. Let’s start by understanding memory and focus. Most humans only have the ability to truly focus on something for 10-20 minutes, and the ability to hold roughly 4 – 7 things in their mind at one time. Your short term memory only lasts for about 15-30 seconds. Knowing this we can try to understand what our minds do to combat forgetting to do something. In order for us not to forget our central processing unit (brain) needs to constantly keep revisiting those tasks. Think about it, when you haven’t written something down your mind constantly revisits it. “I have to remember to wash the sheets”, “Bernoulli’s principle of fluid dynamics states that an increase….”, “Remember to wash the sheets”. Now — this wouldn’t be too bad if we always only had 4 things to do. But that isn’t reality. In a day we might have hundreds of things to do. So your mind rapidly revisits them. David Allen of Getting Things Done refers to these as Open Loops. These loops cause us anxiety, induce insomnia, and overall are very stress inducing. I’m sure we’ve all experienced that little nagging voice telling us all the things we need to do tomorrow at 3 o’clock in the morning before an interview.

The beautiful thing about paper or computers, is that they don’t forget. But a computer, or a piece of paper will never be creative or productive on it’s own. In fact, computers and paper are nothing unless you put a human in the mix (don’t get me started about AI). We can use these tools, in a symbiotic relationship that utilizes both strengths. The human’s ability to be creative and structured, and the paper or computer’s ability to remember. This is what a to-do list is. What it does, is frees us from the chaos of these open loops, and let’s us focus on what’s important. The actual task at hand.

But we all know a piece of paper and pencil, isn’t a panacea to solve all of our productivity woes. If it was, there wouldn’t be an infinite number of to-do list applications on the internet. So, what’s missing from our good old fashioned paper and pencil to-do list?

In my opinion 2 things:

  1. Lack of an Effective Prioritization Framework – If you’re reading this post, you’ve been there. You’ve dumped everything down for today, and you start ordering the tasks based on their priority. What you prioritized today, might be different than tomorrow. Why? Because there’s often no rhyme or reason other than “this is important, my wife will be pissed if I don’t do this”. Another thing humans suck at — prioritization. Because we let our emotions override what we should be doing, for what we want to be doing.
    What you should be doing, for any given to-do list, is the closest, easiest, most valuable item on the list. What this means is that you work on the smallest most impactful task, that is due soon. What was the definition of Productivity? Exactly. The more small impactful things you get done, the more productive you are. It also helps to keep you consistent by solidifying tiny big wins as you go. Lastly, it pushes difficult meaningless tasks to the back, so that you aren’t busy being unproductive. This is called the Impact-Effort or Priority-Difficulty matrix. You can read more about it here, or in Getting Things Done by David Allen.
  2. A Tendency to Overwhelm – The other problem with the common paper and pencil, and a lot of digital to-do lists, is that they keep things too visible for us. Just like seeing small wins by seeing that tasks are complete has a positive impact on our psyche. Seeing a massive, never ending, infinite list has a negative impact. Remember, that we really can only focus on 4-7 things at once, so any more than that and we have to rapidly context switch. We get a sense of overwhelm, and discouragement that make us want to turn away from our trusty paper’s memory. Because it’s too much. So we burn that to-do list, and we turn back to our trusty fallible human brain, as ironic as that is. This is where pen and paper fall down, and where machines really shine. Because humans are emotional, and paper and pencil can’t do anything without human intervention. It becomes very difficult to build an effective prioritization method. Without priority, we must see everything all at once.
    Where machines are brilliant, is that they can remove emotion from decisions, and they do it with perfect accuracy. That’s what computers are meant to do, and what makes them a perfect prioritization companion. A deterministic algorithm means that given the same input, the computer will give the exact same output, every time. That’s exactly what we need an algorithm for prioritizing.
    When we have an effectively prioritized list, it allows us to do something marvelous. It allows us to only see what we need to see right now, and be certain that it’s the most important items. When we only see 10 things, we’re now no longer intimidated, we’re invigorated, because we’re up to the challenge.

3. Give yourself room to breathe.

Congratulations! You’ve made it this far. You now are consistently tracking and nailing things you need to do. You’re working off a list that doesn’t overwhelm you, and you’re confident that you’re doing the right thing. You know in the back of your head that the project has taken some interesting turns, and occasionally tasks keep popping up that just aren’t in alignment with the project anymore. Or worse yet, things that used to be unimportant, all of a sudden have become important.
The final puzzle piece to being more productive, and efficient is review. If you look at the popular software development frameworks like agile or Xtreme. They all contain an aspect of review. Typically in the form of a retrospective. The idea is that you work a 2 week sprint, and then you take a moment to review what you did, and how you did it. The same thing goes for your to-do list. Because the doing side of your life, is just a collection of projects that need, well, doing. So we have to take some time to review our lists. The popular Bullet Journal technique has this built in with pen and paper. As you carry forward through pages, you bring items from old pages forward. You can use this to clarify, trim, or remove completely. It’s the equivalent of tidying your workspace, so you have room to breathe, and think.
What does this look like with a digital to-do list. Well, it’s the time to recharacterize your tasks. You’ll notice I didn’t say reprioritize your tasks. Because the way a task is prioritized never changes, but the characteristics of the tasks may, and where they sit in the line might. Maybe that low impact thing you had on the list, is now high impact. Maybe the deadline got moved up. Maybe the task is no longer important to the project. These are things we have to use our human brains to do, and this is how we declutter our minds. This review time is a perfect time to reflect on what you did well, what didn’t work so well, and what tasks really matter. If you’re not doing this as part of your to-do list management, I urge you to try. Every two weeks, give yourself permission to take 15-20 minutes to review your lists of things to do. Recharacterize the tasks, sweep up old tasks that no longer make sense, and clarify the others. I would be willing to bet you find this time both satisfying and refreshing while it opens and clarifies your thoughts and mind.

I want to thank you for reading, and hope that these 3 techniques can help you on your journey of becoming the most productive you yet. It has been wonderful sharing my experiences with you, and I hope that it sparks some conversations, or thoughts in you all. I hope that if you apply these techniques you’ll see marked improvement in both productivity and mental clarity.

If this blog post struck a chord, I’ll invite you to try out Fuss, and see how these techniques are built directly into the tool. If you’re interested in helping make Fuss better, I would love that. Right now, I have a freemium model to help cover some of the hosting costs. However, if you’d like to use the tool for free in exchange for feedback, I would love that too. You can email me here.

As always, stay well, and Happy Coding!

PL

Improved productivity means less human sweat, not more. — Henry Ford

References