diff --git a/TODO.org b/TODO.org
index 42fa47440bb5ce7f8771a5eb0410219de43e358c..5c13dd893145e2c3d51fc5897f8556a476633c60 100644
--- a/TODO.org
+++ b/TODO.org
@@ -124,7 +124,8 @@ sub autogen_C_logging_code
 
 
 *** TODO Make function in python that puts code into c function
-*** TODO Make function in python that generates c-function from a list of arguments
+*** DONE Make function in python that generates c-function from a list of arguments
+    CLOSED: [2019-10-29 Tue 23:52]
 *** TODO Resolve current issue malloc
 ➜  binary_c-python git:(master) ✗ python python_API_test.py 
 Traceback (most recent call last):
diff --git a/binary_c_python.h b/binary_c_python.h
index d4381f6885e5596556dc5bda3291af5e3540a7d7..0122aa7885538b422f0ffe8c29420b33c94c16f6 100644
--- a/binary_c_python.h
+++ b/binary_c_python.h
@@ -17,8 +17,6 @@ int run_binary_with_log (char * argstring,
                 char ** outstring,
                 int * nbytes);
 
-
-
 int return_arglines(char ** buffer,
                int * nbytes);
 
diff --git a/binaryc_python_utils/logging_functions.py b/binaryc_python_utils/logging_functions.py
index 1d4aa71c3b6fbca3ca2222ad77ccae3c0215edac..c0c3645e973c1bcb7d69009a9174567abc2b8c28 100644
--- a/binaryc_python_utils/logging_functions.py
+++ b/binaryc_python_utils/logging_functions.py
@@ -1,4 +1,11 @@
+import textwrap
 # Functions for the automatic logging of stuff
+# https://stackoverflow.com/questions/41954269/create-c-function-pointers-structure-in-python
+# https://stackabuse.com/enhancing-python-with-custom-c-extensions/ Read
+# https://stackoverflow.com/questions/49941617/runtime-generation-and-compilation-of-cython-functions
+# https://realpython.com/cpython-source-code-guide/
+# https://docs.python.org/3.6/c-api/index.html
+
 
 # Perl code for autogeneration
 # sub autogen_C_logging_code
@@ -69,19 +76,15 @@ def autogen_C_logging_code(logging_dict):
     # Check if the input is of the correct form 
     if not type(logging_dict)==dict:
         print("Error: please use a dictionary as input")
+        return None
 
-    #
     code = ''
-
     # Loop over dict keys
     for key in logging_dict:
-        print('{}'.format(key))
-
         logging_dict_entry = logging_dict[key]
 
         # Check if item is of correct type:
         if type(logging_dict_entry)==list:
-            print(logging_dict_entry)
 
             # Construct print statement
             code += 'PRINTF("{}'.format(key)
@@ -92,14 +95,119 @@ def autogen_C_logging_code(logging_dict):
             # Add format keys
             for param in logging_dict_entry:
                 code += ',((double)stardata->{})'.format(param)
-            code += ');'
+            code += ');\n'
 
         else:
             print('Error: please use a list for the list of parameters that you want to have logged')
+    code = code.strip()
+    # print("MADE AUTO CODE\n\n{}\n\n{}\n\n{}\n".format('*'*60, repr(code), '*'*60))
 
+    return code
 
-    print(repr(code))
 
-autogen_C_logging_code({'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], 'my_sss2': ['model.time', 'star[1].mass']})
+autogen_C_logging_code(
+    {
+        'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], 
+        'my_sss2': ['model.time', 'star[1].mass']
+    }
+)
 
+####################################################################################
+
+# sub binary_c_log_code
+# {
+#     my ($code) = @_;
+#     return "
+# #pragma push_macro(\"MAX\")
+# #pragma push_macro(\"MIN\")
+# #undef MAX
+# #undef MIN
+# #include \"binary_c.h\"
+
+# void custom_output_function(SV * x);
+# SV * custom_output_function_pointer(void);
+
+# SV * custom_output_function_pointer()
+# {
+#     /*
+#      * use PTR2UV to convert the function pointer 
+#      * &custom_output_function to an unsigned int,
+#      * which is then converted to a Perl SV
+#      */
+#     return (SV*)newSVuv(PTR2UV(&custom_output_function));
+# }
+
+# void custom_output_function(SV * x)
+# {
+#     struct stardata_t * stardata = (struct stardata_t *)x;
+#     $code;
+# }
+# #undef MAX 
+# #undef MIN
+# #pragma pop_macro(\"MIN\")
+# #pragma pop_macro(\"MAX\")
+# ";
+# }
+
+# And then to use it via 
+#     $population->set(
+#         C_logging_code => '
+#              PRINTF("MY_STELLAR_DATA %g %g %g %g\n",
+#                  stardata->model.time,
+#                  stardata->star[0].mass,
+#                  stardata->model.probability,
+#                  stardata->model.dt);
+#                        '
+#     );
+
+
+
+def binary_c_log_code(code):
+    """
+    Function to construct the code to construct the custom logging function
+    """
+    custom_logging_function_string = """
+        #pragma push_macro(\"MAX\")
+        #pragma push_macro(\"MIN\")
+        #undef MAX
+        #undef MIN
+        #include \"binary_c.h\"
+
+        void custom_output_function(SV * x);
+        SV * custom_output_function_pointer(void);
+
+        SV * custom_output_function_pointer()
+        {{
+            /*
+             * use PTR2UV to convert the function pointer 
+             * &custom_output_function to an unsigned int,
+             * which is then converted to a Perl SV
+             */
+            return (SV*)newSVuv(PTR2UV(custom_output_function));
+        }}
+
+        void custom_output_function(SV * x)
+        {{
+            struct stardata_t * stardata = (struct stardata_t *)x;
+            {code};
+        }}
+
+        #undef MAX 
+        #undef MIN
+        #pragma pop_macro(\"MIN\")
+        #pragma pop_macro(\"MAX\")
+    """.format(code=code)
+
+    print(textwrap.dedent(custom_logging_function_string))
+    # return custom_logging_function_string
+
+
+code = autogen_C_logging_code(
+    {
+        'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], 
+        'my_sss2': ['model.time', 'star[1].mass']
+    }
+)
+
+binary_c_log_code(code)