Do you think that Python will replace Java and C# in the future as the main language for enterprise applications and micro services apps?

Java to C# – C# to Java

Java to C# – C# to Java

In this post, we bring you a much needed Rosetta Stone — an explanatory bridge between these two technologies

Originally published by Andy Macdonald at https://medium.com
Java and C# are incredibly similar. Both languages are somewhat derived from C++ and from similar first principles.

Java was developed in 1995 to create a language with a simpler programming model than C++ while still preserving some of the same syntax of the language to facilitate developers transitioning to it.

C# was developed in 2000 by Microsoft as part of its .NET drive in order to develop a language and set of technologies that could address some of the perceived weaknesses of the C++ language. It was also developed with quite heavy “inspiration” from the Java language.

Despite the similarities between the languages and sharing some common ground, transitioning from one technology to the other for a developer well-practised in one technology can be quite tricky.

Innovation happens best when there is collaboration between people of different mindsets — yet users of C# and Java can be somewhat tribalistic.

To that end, I thought it would be useful to put together a sort of guide to help people thinking about or starting to transition between these two technologies. It would also be nice in some way to facilitate a bit more collaboration between these two worlds — hopefully to do my bit to reduce the needless gulf that exists between them.

Some of the similarities right off the bat:

Java is a language that runs in a virtual machine environment (JVM) and runs bytecode that the Java compiler generates.

For C#, the situation is similar. It is a language that runs on the .NET framework and the CLR runtime. It uses a similar intermediary language to Java bytecode called MSIL which gets run via CLR.

Naming and Conventions

Some of the key and most immediately obvious differences in nomenclature, syntax, and conventions are:

  • “Projects” (Java) — “Solutions” (C#)
  • In Java, methods use lowerCamelCase (bar.doAThing()), whilst in C# public methods use PascalCase (bar.DoAThing())
  • In C#, interfaces are always prefixed with an I, as in IUserService<T>, instead of UserService<T>** **in Java
  • In Java, a string is a String** **— in C# a string is a string
  • “POJO” (Java) — “POCO” (C#)
  • Packages (Java) — Namespaces (C#)

Package (Java)

package dev.andymacdonald;

// Code goes here

Namespace (C#)

namespace Dev.AndyMacdonald 
{
  // Code goes here
}

Syntax

**Java has <strong>final</strong> variables — C# has **<strong>readonly</strong>

A key difference here is that Java final variables can be assigned once anywhere in the class, whereas C#’s readonly variables can only be assigned in the constructor.

C# has <strong>out</strong> and <strong>ref</strong> parameters to allow passing arguments by reference — Java doesn’t

It can manipulate objects and variables by reference, but in a method, these arguments are passed by a value. With C#, we can override this behaviour with the out and ref keywords.

Annotations (Java) — attributes (C#)

These are basically equivalent concepts and just differ in actual syntax. Both annotations and attributes can be accessed via each language’s respective Reflection API implementation.

Java annotation:

@PersonallyIdentifiable
private String fullName;

C# attribute:

[PersonallyIdentifiable]
private string fullName;

Getters and setters or Project Lombok (Java) — C# properties

C# really overtakes Java here with its built-in properties* *feature. In the standard JDK, there isn’t an equivalent to this, and instead, in Java, getters and setters must be written for each field requiring an accessor.

These are often just generated by the developer with their IDE as a cheat … still a bit tedious, though.

Java getters and setters:


public class Element 
{
   
  private String symbol;   
  private String name;   
  private int atomicNumber;
  public int getAtomicNumber() 
  {
    return this.atomicNumber;
  }
  public String getSymbol() 
  {
    return this.symbol;
  }
  public String getName() 
  {
    return this.name; 
  }
  public void setAtomicNumber(int atomicNumber) 
  {
    this.atomicNumber = atomicNumber;
  }
  public void setName(String name) 
  {
    this.name = name;
  }
  public void setSymbol(String symbol) 
  {
    this.symbol = symbol;
  }
}

Many Java projects incorporate Project Lombok, which adds getters, setters, equals, and hash code (plus other useful boilerplates) at compile time.

Project Lombok — not part of the standard library:

@Getter @Setter
public class Element 
{
   
  private String symbol;   
  private String name;   
  private int atomicNumber;
}

C# built-in properties feature:

public class Element 
{

  public string Symbol { get; set; }     
  public string Name { get; set; }     
  public int AtomicNumber { get; set; }
}

Loops

Java for each loop:

List<Integer> fibNumbers = Arrays.asList(0, 1, 1, 2, 3, 5, 8, 13);
int count = 0;
for (int element: fibNumbers)
{
    count++;
    System.out.println(String.format("Element #%s: %s", count, element));
}
System.out.println(String.format("Number of elements: %s", count));

C# for each loop:

var fibNumbers = new List<int> { 0, 1, 1, 2, 3, 5, 8, 13 };
int count = 0;
foreach (int element in fibNumbers)
{
    count++;
    Console.WriteLine($"Element #{count}: {element}");
}
Console.WriteLine($"Number of elements: {count}");

Implementing interfaces/inheritance

Inheritance and implementing interfaces isn’t drastically different between the two languages. Java uses the extends or implements keywords; C# uses C++ syntax (derivation declaration) B : A for defining inheritance.

Defining and implementing an interface with methods in Java:

package dev.andymacdonald;


import java.util.ArrayList;
import java.util.List;

interface Fish
{
   void swim();
}

class Salmon implements Fish
{

   public void swim()
   {
      System.out.println("Salmon.Fish");
   }
}

class Cod implements Fish
{
   public void swim()
   {
      System.out.println("Cod.Swim");
   }
}

public class Program
{
   public static void main()
   {
      List<Fish> fishes = new ArrayList<>();
      fishes.add(new Salmon());
      fishes.add(new Cod());

      for (Fish fish : fishes)
      {
         fish.swim();
      }
   }
}

Defining and implementing an interface with methods in C#:

using System;
using System.Collections.Generic;

namespace Dev.AndyMacdonald 
{
    interface Fish
    {
        void Swim();
    }
    class Salmon : Fish
    {
        public void Swim()
        {
            Console.WriteLine("Salmon.Fish");
        }
    }
    class Cod : Fish
    {
        public void Swim()
        {
            Console.WriteLine("Cod.Swim");
        }
    }
    class Program
    {
        static void Main()
        {
            List<Fish> fishes = new List<Fish>();
            fishes.Add(new Salmon());
            fishes.Add(new Cod());
            foreach (Fish fish in fishes)
            {
                fish.Swim();
            }
        }
    }
}

Pointers

Quite simply, Java just doesn’t do pointers, whereas in C# it is possible to do pointer arithmetic and manipulation.

 unsafe {
  int a = 25;
  int * ptr = &a;
  Console.WriteLine($"Value of pointer is {*ptr}");
}

IDE

Visual Studio

C# developers traditionally and typically use the Visual Studio IDE. This is a situation borne out of the origins of .NET being a closed-source technology. Microsoft developed Visual Studio** **to be a one-stop shop for all things .NET.

Java went down a different route, offering much more developer choice in tooling from the outset. That’s why there’s a much greater range of IDEs for Java development (e.g., IntelliJ, Eclipse, NetBeans). Gradually the landscape for .NET developers has shifted, and more IDEs and developer choice has been offered over the years.

IntelliJ (Java) — Rider (C#)

Users of JetBrains IDEs will find the transition from one IDE to another very smooth if they choose to make a switch to the respective JetBrains IDE in the technology they are targeting. Keyboard shortcuts, IDE layout, and even some plugins are equivalent or comparable — virtually the same IDE.

Dependency Management

Maven (Java) — NuGet and dotnet CLI (C#)

Maven is a tool responsible for dependency management and the life cycle of the building of typically Java and JVM applications. That said, it is pretty flexible, has 1000s of plugins, and can be used to build applications of other languages, such as PHP and JavaScript.

The configurable unit of maven is a pom.xml file that every maven project has. For a project’s submodules, it is possible to have a pom file per submodule which inherits from a parent. Maven uses a remote server or repository of some kind to host and retrieve packages.

Maven pom.xml file (Java):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>dev.andymacdonald</groupId>
    <artifactId>fish-app</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

At the simplest level, you can test and build a Maven project with the following command:

mvn clean install

And create a package with this:

mvn clean package

And finally, deploy a package like this:

mvn clean deploy

NuGet fulfills a similar, though not identical role in .NET to Maven. NuGet can use a few different configuration files but commonly uses .csproj*. *As with Maven, NuGet uses a server/repository that can host packages.

NuGet .csproj file:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <AssemblyName>MSBuildSample</AssemblyName>
    <OutputPath>Bin\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="helloworld.cs" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="MyDependency" version="1.0.0" />
  </ItemGroup>  
  <Target Name="Build">
    <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
    <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
  </Target>
</Project>

NuGet’s primary role is package management, construction, and deployment. Java developers will notice that it doesn’t really have the same concept of build phases as Maven does. Additionally, .NET developers don’t tend to edit their build files manually as Java developers do with pom.xml files, preferring to manipulate them in their IDE instead.

Packages can be built, packaged, and deployed to NuGet with the following nuget commands:

nuget spec
nuget pack {nuspec file}
nuget push {package file} {apikey} -Source {host url}

If you want to run the tests for your .NET application, you can run the following dotnet CLI command:

dotnet test

The dotnet CLI can also be used as a wrapper around nuget commands.

Application Servers

Apache Tomcat (Java) — IIS (ASP.NET)

Tomcat is an open-source web server and servlet container from the Apache Foundation. Though there are many other application servers used widely in Java, it is a pretty common choice for most enterprise-software companies. It works across pretty much every operating system (e.g., Windows, Unix, Linux, and Mac OS).

.NET projects are typically deployed on IIS, a web server that only runs on Windows. While its portability is limited, it’s a pretty popular choice for Windows developers because of its ease of use and simplicity while still offering some advanced configuration options.

… But Wait!

For .NET Core web applications, you can package them to run as standalone web applications — allowing you to run them like this:

dotnet <app_assembly>.dll

In the same way you can run a Java Spring Boot web*** ***application (which has a self-contained Tomcat server):

java -jar <my-application>.jar

And visit your shiny new web app like this:

http://<serveraddress>:<port>

Libraries and Frameworks

Spring Framework (Java) — ASP.NET (C#)

The Spring Framework is a framework and IoC container for Java. In short, the Spring framework is responsible for instantiating objects (beans) and managing the life cycle of these beans in memory.

Create an ApplicationContext* *(similar to the concept of a Startup in ASP.NET). This example uses Spring Boot:

@SpringBootApplication
public class HumanApplication
{
   public static void main(String[] args) 
   {
      SpringApplication.run(HumanApplication.class, args);
   }
}

Create an interface:

public interface Organ<T>
{  
   void function();
}

Implement the Organ<T> interface:

@Component
public class Heart implements Organ<Heart>
{
    public Heart() {}
    public void function() 
    {
        System.out.println("Buh-dump");
    }
}

Constructor injection of Organ dependencies list into a Human service:

@Service
public class Human 
{
    private static final int MAX_SECONDS_OF_LIFE = 3000;
    private List<Organ> organs;
    public Human(List<Organ> organs) 
    {
        this.organs = organs;
    }
    @PostConstruct
    public void live() 
    {
        for (int i = 0; i < MAX_SECONDS_OF_LIFE; i++) 
        {
            organs.forEach(organ -> organ.function());
        }
    }
}

Run the application …

It’s aliiiiiiive:

Buh-dump
Buh-dump
Buh-dump
Buh-dump
...

Spring also ships with a handy suite of modules and packages.

In the core Spring packages, and in the convention-over-configuration extension to the framework, Spring Boot, useful combinations of existing and bespoke technologies are provided for developers wanting access to common libraries to kickstart a project with all that they may need, rather than having to write or track down these utilities themselves:

  • RestTemplate (spring-web — for constructing REST and HTTP requests)
  • JdbcTemplate (spring-data — for constructing JDBC queries and statements)
  • Spring Security (for creating and managing application security models)
  • ObjectMapper (spring-core — useful utility for mapping POJOs from Jackson)
  • etc.

ASP.NET fulfills a similar role in the world of C#, providing IoC functionality, commonly used technologies, and utilities in a single framework. However, ASP.NET generally only provides IoC functionality for web applications, whereas the Spring Framework provides this for any application type.

In terms of dependency inversion, it is possible to do very similar things in ASP.NET as in Spring.

As before, define the needed interface and concrete implementation:

public interface Organ<T>
{  
   void Function();
}
public class Heart : Organ<Heart>
{
    public Heart() {}
    public void Function() 
    {
        Console.WriteLine("Buh-dump");
    }
}

Invoke functions of injected dependencies:

public class Human
{

   private List<IOrgan> _organs;
 
   public Human(List<IOrgan> organs)
   {
      _organs = organs;
      this.Live();
   }
   public void Live()
   {
      organs.ForEach(organ =>
      {
         organ.Function();
      });
   }
}

Define a Startup and register services:

public class Startup  
{    
  public void ConfigureServices(IServiceCollection services)
  {    
    services.AddTransient<IList<IOrgan>>(p => p.GetServices<IOrgan>().ToList());
  }
}

ASP.NET also fulfills the role of providing many useful libraries and utilities to accelerate development of your project.

Streams (Java) — LINQ (C#)

Both Java and C# have mechanisms to simplify the reduction of data sets — Streams and LINQ.

There are some differences and gaps between the two technologies but if you have familiarity with one, you’ll be able to get up and running fairly quickly with the other.

Java Streams:

List<Student> studentList = Arrays.asList( 
    new Student(1, "John", 18, 1),
    new Student(2, "Steve", 21, 1),
);
List<String> studentNames = studentList.stream()
    .filter(s -> s.getAge() > 18)
    .filter(s -> s.getStandardID() > 0)
    .map(s -> s.getName()).collect(Collectors.toList());
studentNames.forEach(name -> System.out.println(name));

LINQ Query (C#):

IList<Student> studentList = new List<Student>() { 
    new Student() { StudentID = 1, StudentName = "John", Age = 18, StandardID = 1 } ,
    new Student() { StudentID = 2, StudentName = "Steve",  Age = 21, StandardID = 1 }
};
var studentNames = studentList.Where(s => s.Age > 18)
                        .Where(st => st.StandardID > 0)
                        .Select(s => s.StudentName);
foreach(var name in studentNames) {   
    Console.WriteLine(name);
}

Apache Commons (Java) — CommonLibrary.NET (C#)

Apache Commons*** ***provides Java developers with a collection of several independently released, useful components and utilities for the purposes of accelerating development.

If you’re in need of a utility to work with ZIP files or a set of utilities for working with mathematical expressions and formulae, then Apache Commons has you covered.

In a similar way, CommonLibrary.NET covers these bases too — there are some key differences in naming of some components and modules, but for the most part, they are pretty much equivalent in their purpose.

That said, unlike Apache Commons, CommonLibrary.NET is quite old and isn’t very commonly used in projects anymore. If you’re after a continuously updated, curated list of libraries for each respective technology, I highly recommend these two lists:

akullpp/awesome-java

quozd/awesome-dotnet

Testing Libraries

JUnit (Java) — NUnit (C#)

Java’s ever-dependable JUnit library has a direct equivalent in C#.

NUnit has almost equivalent functionality to JUnit and is a popular choice for C# developers.

JUnit:

@Test
public void complexNumberTest()
{
    ComplexNumber result = someCalculation();
    Assert.assertEquals("Real", 5.2, result.getRealPart());
    Assert.assertEquals("Imaginary" 3.9, result.getImaginaryPart());
}

NUnit:

[Test]
public void ComplexNumberTest()
{
    ComplexNumber result = SomeCalculation();
    Assert.Multiple(() =>
    {
        Assert.AreEqual(5.2, result.RealPart, "Real");
        Assert.AreEqual(3.9, result.ImaginaryPart, "Imaginary");
    });
}

(Rumour has it NUnit started life as the JUnit source code modified to run in C#.)

Mockito (Java) — Moq (C#)

As with JUnit and NUnit, comparable functionality exists between Java’s Mockito and C#’s Moq library.

Mockito:

Foo mockFoo = mock(Foo.class);
when(mockFoo.doSomething("ping")).thenReturn(true);

Moq:

var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);

That’s It

Thanks for Reading!

I obviously couldn’t fit every difference, similarity, and detail in this article —* *it’s already far too long.

I hope at least I’ve covered enough ground to make you feel confident to make a switch and see how the other half lives.

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

Java Tutorial for Absolute Beginners

100+ Java Interview Questions and Answers In 2019

Python vs Java: Understand Object Oriented Programming

Angular 7 + Spring Boot CRUD Example

Build a Simple CRUD App with Spring Boot and Vue.js

How to Write Python C Extension Modules using the Python API

How to Write Python C Extension Modules using the Python API

There are several ways in which you can extend the functionality of Python. One of these is to write your Python module in C or C++. In this tutorial, you’ll discover how to use the Python API to write Python C extension modules.

You’ll learn how to:

  • Invoke C functions from within Python
  • Pass arguments from Python to C and parse them accordingly
  • Raise exceptions from C code and create custom Python exceptions in C
  • Define global constants in C and make them accessible in Python
  • Test, package, and distribute your Python C extension module

Table of Contents

  • Extending Your Python Program
  • Writing a Python Interface in C
    • Understanding fputs()
    • Writing the C Function for fputs()
    • Wrapping fputs()
    • Writing the Init Function
    • Putting It All Together
  • Packaging Your Python C Extension Module
    • Building Your Module
    • Running Your Module
  • Raising Exceptions
    • Raising Exceptions From C Code
    • Raising Custom Exceptions
  • Defining Constants
  • Testing Your Module
  • Considering Alternatives
  • Conclusion
Extending Your Python Program

One of the lesser-known yet incredibly powerful features of Python is its ability to call functions and libraries defined in compiled languages such as C or C++. This allows you to extend the capabilities of your program beyond what Python’s built-in features have to offer.

There are many languages you could choose from to extend the functionality of Python. So, why should you use C? Here are a few reasons why you might decide to build a Python C extension module:

  1. To implement new built-in object types: It’s possible to write a Python class in C, and then instantiate and extend that class from Python itself. There can be many reasons for doing this, but more often than not, performance is primarily what drives developers to turn to C. Such a situation is rare, but it’s good to know the extent to which Python can be extended.

  2. To call C library functions and system calls: Many programming languages provide interfaces to the most commonly used system calls. Still, there may be other lesser-used system calls that are only accessible through C. The os module in Python is one example.

This is not an exhaustive list, but it gives you the gist of what can be done when extending Python using C or any other language.

To write Python modules in C, you’ll need to use the Python API, which defines the various functions, macros, and variables that allow the Python interpreter to call your C code. All of these tools and more are collectively bundled in the Python.h header file.

Writing a Python Interface in C

In this tutorial, you’ll write a small wrapper for a C library function, which you’ll then invoke from within Python. Implementing a wrapper yourself will give you a better idea about when and how to use C to extend your Python module.

Understanding fputs()

fputs() is the C library function that you’ll be wrapping:

int fputs(const char *, FILE *)

This function takes two arguments:

  1. const char * is an array of characters.
  2. FILE * is a file stream pointer.

fputs() writes the character array to the file specified by the file stream and returns a non-negative value. If the operation is successful, then this value will denote the number of bytes written to the file. If there’s an error, then it returns EOF. You can read more about this C library function and its other variants in the manual page entry.

Writing the C Function for fputs()

This is a basic C program that uses fputs() to write a string to a file stream:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    FILE *fp = fopen("write.txt", "w");
    fputs("Real Python!", fp);
    fclose(fp);
    return 1;
}

This snippet of code can be summarized as follows:

  1. Open the file write.txt.
  2. Write the string "Real Python!" to the file.

Note: The C code in this article should build on most systems. It has been tested on GCC without using any special flags.

In the following section, you’ll write a wrapper for this C function.

Wrapping fputs()

It might seem a little weird to see the full code before an explanation of how it works. However, taking a moment to inspect the final product will supplement your understanding in the following sections. The code block below shows the final wrapped version of your C code:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &filename)) {

        return NULL;

    }


    FILE *fp = fopen(filename, "w");

    bytes_copied = fputs(str, fp);

    fclose(fp);


    return PyLong_FromLong(bytes_copied);

}

This code snippet references three object structures:

  1. PyObject
  2. PyArg_ParseTuple()
  3. PyLong_FromLong()

These are used for data type definition for the Python language. You’ll go through each of them now.

PyObject

PyObject is an object structure that you use to define object types for Python. All Python objects share a small number of fields that are defined using the PyObject structure. All other object types are extensions of this type.

PyObject tells the Python interpreter to treat a pointer to an object as an object. For instance, setting the return type of the above function as PyObject defines the common fields that are required by the Python interpreter in order to recognize this as a valid Python type.

Take another look at the first few lines of your C code:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Snip */

In line 2, you declare the argument types you wish to receive from your Python code:

  1. char *str is the string you want to write to the file stream.
  2. char *filename is the name of the file to write to.

PyArg_ParseTuple()

PyArg_ParseTuple() parses the arguments you’ll receive from your Python program into local variables:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &filename)) {

        return NULL;

    }


    /* Snip */

If you look at line 6, then you’ll see that PyArg_ParseTuple() takes the following arguments:

  • args are of type PyObject.

  • "ss" is the format specifier that specifies the data type of the arguments to parse. (You can check out the official documentation for a complete reference.)

  • &str and &filename are pointers to local variables to which the parsed values will be assigned.

PyArg_ParseTuple() evaluates to false on failure. If it fails, then the function will return NULL and not proceed any further.

fputs()

As you’ve seen before, fputs() takes two arguments, one of which is the FILE * object. Since you can’t parse a Python textIOwrapper object using the Python API in C, you’ll have to use a workaround:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &filename)) {

        return NULL;

    }


    FILE *fp = fopen(filename, "w");

    bytes_copied = fputs(str, fp);

    fclose(fp);


    return PyLong_FromLong(bytes_copied);

}

Here’s a breakdown of what this code does:

  • In line 10, you’re passing the name of the file that you’ll use to create a FILE * object and pass it on to the function.
  • In line 11, you call fputs() with the following arguments:
    • str is the string you want to write to the file.
    • fp is the FILE * object you defined in line 10.

You then store the return value of fputs() in bytes_copied. This integer variable will be returned to the fputs() invocation within the Python interpreter.

PyLong_FromLong(bytes_copied)

PyLong_FromLong() returns a PyLongObject, which represents an integer object in Python. You can find it at the very end of your C code:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &filename)) {

        return NULL;

    }


    FILE *fp = fopen(filename, "w");

    bytes_copied = fputs(str, fp);

    fclose(fp);


    return PyLong_FromLong(bytes_copied);

}

Line 14 generates a PyLongObject for bytes_copied, the variable to be returned when the function is invoked in Python. You must return a PyObject* from your Python C extension module back to the Python interpreter.

Writing the Init Function

You’ve written the code that makes up the core functionality of your Python C extension module. However, there are still a few extra functions that are necessary to get your module up and running. You’ll need to write definitions of your module and the methods it contains, like so:

static PyMethodDef FputsMethods[] = {
    {"fputs", method_fputs, METH_VARARGS, "Python interface for fputs C library function"},
    {NULL, NULL, 0, NULL}
};


static struct PyModuleDef fputsmodule = {
    PyModuleDef_HEAD_INIT,
    "fputs",
    "Python interface for the fputs C library function",
    -1,
    FputsMethods
};

These functions include meta information about your module that will be used by the Python interpreter. Let’s go through each of the structs above to see how they work.

PyMethodDef

In order to call the methods defined in your module, you’ll need to tell the Python interpreter about them first. To do this, you can use PyMethodDef. This is a structure with 4 members representing a single method in your module.

Ideally, there will be more than one method in your Python C extension module that you want to be callable from the Python interpreter. This is why you need to define an array of PyMethodDef structs:

static PyMethodDef FputsMethods[] = {
    {"fputs", method_fputs, METH_VARARGS, "Python interface for fputs C library function"},
    {NULL, NULL, 0, NULL}
};

Each individual member of the struct holds the following info:

  • "fputs" is the name the user would write to invoke this particular function.

  • method_fputs is the name of the C function to invoke.

  • METH_VARARGS is a flag that tells the interpreter that the function will accept two arguments of type PyObject*:

    1. self is the module object.
    2. args is a tuple containing the actual arguments to your function. As explained previously, these arguments are unpacked using PyArg_ParseTuple().
  • The final string is a value to represent the method docstring.

PyModuleDef

Just as PyMethodDef holds information about the methods in your Python C extension module, the PyModuleDef struct holds information about your module itself. It is not an array of structures, but rather a single structure that’s used for module definition:

static struct PyModuleDef fputsmodule = {
    PyModuleDef_HEAD_INIT,
    "fputs",
    "Python interface for the fputs C library function",
    -1,
    FputsMethods
};

There are a total of 9 members in this struct, but not all of them are required. In the code block above, you initialize the following five:

  1. PyModuleDef_HEAD_INIT is a member of type PyModuleDef_Base, which is advised to have just this one value.

  2. "fputs" is the name of your Python C extension module.

  3. The string is the value that represents your module docstring. You can use NULL to have no docstring, or you can specify a docstring by passing a const char * as shown in the snippet above. It is of type Py_ssize_t. You can also use PyDoc_STRVAR() to define a docstring for your module.

  4. -1 is the amount of memory needed to store your program state. It’s helpful when your module is used in multiple sub-interpreters, and it can have the following values:

    • A negative value indicates that this module doesn’t have support for sub-interpreters.
    • A non-negative value enables the re-initialization of your module. It also specifies the memory requirement of your module to be allocated on each sub-interpreter session.
  5. FputsMethods is the reference to your method table. This is the array of PyMethodDef structs you defined earlier.

For more information, check out the official Python documentation on PyModuleDef.

PyMODINIT_FUNC

Now that you’ve defined your Python C extension module and method structures, it’s time to put them to use. When a Python program imports your module for the first time, it will call PyInit_fputs():

PyMODINIT_FUNC PyInit_fputs(void) {
    return PyModule_Create(&fputsmodule);
}

PyMODINIT_FUNC does 3 things implicitly when stated as the function return type:

  1. It implicitly sets the return type of the function as PyObject*.
  2. It declares any special linkages.
  3. It declares the function as extern “C.” In case you’re using C++, it tells the C++ compiler not to do name-mangling on the symbols.

PyModule_Create() will return a new module object of type PyObject *. For the argument, you’ll pass the address of the method structure that you’ve already defined previously, fputsmodule.

Note: In Python 3, your init function must return a PyObject * type. However, if you’re using Python 2, then PyMODINIT_FUNC declares the function return type as void.

Putting It All Together

Now that you’ve written the necessary parts of your Python C extension module, let’s take a step back to see how it all fits together. The following diagram shows the components of your module and how they interact with the Python interpreter:

When you import your Python C extension module, PyInit_fputs() is the first method to be invoked. However, before a reference is returned to the Python interpreter, the function makes a subsequent call to PyModule_Create(). This will initialize the structures PyModuleDef and PyMethodDef, which hold meta information about your module. It makes sense to have them ready since you’ll make use of them in your init function.

Once this is complete, a reference to the module object is finally returned to the Python interpreter. The following diagram shows the internal flow of your module:

The module object returned by PyModule_Create() has a reference to the module structure PyModuleDef, which in turn has a reference to the method table PyMethodDef. When you call a method defined in your Python C extension module, the Python interpreter uses the module object and all of the references it carries to execute the specific method. (While this isn’t exactly how the Python interpreter handles things under the hood, it’ll give you an idea of how it works.)

Similarly, you can access various other methods and properties of your module, such as the module docstring or the method docstring. These are defined inside their respective structures.

Now you have an idea of what happens when you call fputs() from the Python interpreter. The interpreter uses your module object as well as the module and method references to invoke the method. Finally, let’s take a look at how the interpreter handles the actual execution of your Python C extension module:

Once method_fputs() is invoked, the program executes the following steps:

  1. Parse the arguments you passed from the Python interpreter with PyArg_ParseTuple()
  2. Pass these arguments to fputs(), the C library function that forms the crux of your module
  3. Use PyLong_FromLong to return the value from fputs()

To see these same steps in code, take a look at method_fputs() again:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &filename)) {

        return NULL;

    }


    FILE *fp = fopen(filename, "w");

    bytes_copied = fputs(str, fp);

    fclose(fp);


    return PyLong_FromLong(bytes_copied);

}

To recap, your method will parse the arguments passed to your module, send them on to fputs(), and return the results.

Packaging Your Python C Extension Module

Before you can import your new module, you first need to build it. You can do this by using the Python package distutils.

You’ll need a file called setup.py to install your application. For this tutorial, you’ll be focusing on the part specific to the Python C extension module.

A minimal setup.py file for your module should look like this:

from distutils.core import setup, Extension

def main():
    setup(name="fputs",
          version="1.0.0",
          description="Python interface for the fputs C library function",
          author="<your name>",
          author_email="[email protected]",
          ext_modules=[Extension("fputs", ["fputsmodule.c"])])

if __name__ == "__main__":
    main()

The code block above shows the standard arguments that are passed to setup(). Take a closer look at the last positional argument, ext_modules. This takes a list of objects of the Extensions class. An object of the Extensions class describes a single C or C++ extension module in a setup script. Here, you pass two keyword arguments to its constructor, namely:

  • name is the name of the module.
  • [filename] is a list of paths to files with the source code, relative to the setup script.
[Remove ads](/account/join/)

Building Your Module

Now that you have your setup.py file, you can use it to build your Python C extension module. It’s strongly advised that you use a virtual environment to avoid conflicts with your Python environment.

Navigate to the directory containing setup.py and run the following command:

$ python3 setup.py install

This command will compile and install your Python C extension module in the current directory. If there are any errors or warnings, then your program will throw them now. Make sure you fix these before you try to import your module.

By default, the Python interpreter uses clang for compiling the C code. If you want to use gcc or any other C compiler for the job, then you need to set the CC environment variable accordingly, either inside the setup script or directly on the command line. For instance, you can tell the Python interpreter to use gcc to compile and build your module this way:

$ CC=gcc python3 setup.py install

However, the Python interpreter will automatically fall back to gcc if clang is not available.

Running Your Module

Now that everything is in place, it’s time to see your module in action! Once it’s successfully built, fire up the interpreter to test run your Python C extension module:

>>> import fputs
>>> fputs.__doc__
'Python interface for the fputs C library function'
>>> fputs.__name__
'fputs'
>>> # Write to an empty file named `write.txt`
>>> fputs.fputs("Real Python!", "write.txt")
13
>>> with open("write.txt", "r") as f:
>>>     print(f.read())
'Real Python!'

Your function performs as expected! You pass a string "Real Python!" and a file to write this string to, write.txt. The call to fputs() returns the number of bytes written to the file. You can verify this by printing the contents of the file.

Also recall how you passed certain arguments to the PyModuleDef and PyMethodDef structures. You can see from this output that Python has used these structures to assign things like the function name and docstring.

With that, you have a basic version of your module ready, but there’s a lot more that you can do! You can improve your module by adding things like custom exceptions and constants.

Raising Exceptions

Python exceptions are very different from C++ exceptions. If you want to raise Python exceptions from your C extension module, then you can use the Python API to do so. Some of the functions provided by the Python API for exception raising are as follows:

You can use any of these to raise an exception. However, which to use and when depends entirely on your requirements. The Python API has all the standard exceptions pre-defined as PyObject types.

Raising Exceptions From C Code

While you can’t raise exceptions in C, the Python API will allow you to raise exceptions from your Python C extension module. Let’s test this functionality by adding PyErr_SetString() to your code. This will raise an exception whenever the length of the string to be written is less than 10 characters:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &fd)) {

        return NULL;

    }


    if (strlen(str) < 10) {

        PyErr_SetString(PyExc_ValueError, "String length must be greater than 10");

        return NULL;

    }


    fp = fopen(filename, "w");

    bytes_copied = fputs(str, fp);

    fclose(fp);


    return PyLong_FromLong(bytes_copied);

}

Here, you check the length of the input string immediately after you parse the arguments and before you call fputs(). If the string passed by the user is shorter than 10 characters, then your program will raise a ValueError with a custom message. The program execution stops as soon as the exception occurs.

Note how method_fputs() returns NULL after raising the exception. This is because whenever you raise an exception using PyErr_*(), it automatically sets an internal entry in the exception table and returns it. The calling function is not required to subsequently set the entry again. For this reason, the calling function returns a value that indicates failure, usually NULL or -1. (This should also explain why there was a need to return NULL when you parse arguments in method_fputs() using PyArg_ParseTuple().)

Raising Custom Exceptions

You can also raise custom exceptions in your Python C extension module. However, things are a bit different. Previously, in PyMODINIT_FUNC, you were simply returning the instance returned by PyModule_Create and calling it a day. But for your custom exception to be accessible by the user of your module, you need to add your custom exception to your module instance before you return it:

static PyObject *StringTooShortError = NULL;

PyMODINIT_FUNC PyInit_fputs(void) {
    /* Assign module value */
    PyObject *module = PyModule_Create(&fputsmodule);

    /* Initialize new exception object */
    StringTooShortError = PyErr_NewException("fputs.StringTooShortError", NULL, NULL);

    /* Add exception object to your module */
    PyModule_AddObject(module, "StringTooShortError", StringTooShortError);

    return module;
}

As before, you start off by creating a module object. Then you create a new exception object using PyErr_NewException. This takes a string of the form module.classname as the name of the exception class that you wish to create. Choose something descriptive to make it easier for the user to interpret what has actually gone wrong.

Next, you add this to your module object using PyModule_AddObject. This takes your module object, the name of the new object being added, and the custom exception object itself as arguments. Finally, you return your module object.

Now that you’ve defined a custom exception for your module to raise, you need to update method_fputs() so that it raises the appropriate exception:

static PyObject *method_fputs(PyObject *self, PyObject *args) {

    char *str, *filename = NULL;

    int bytes_copied = -1;


    /* Parse arguments */

    if(!PyArg_ParseTuple(args, "ss", &str, &fd)) {

        return NULL;

    }


    if (strlen(str) < 10) {

        /* Passing custom exception */

        PyErr_SetString(StringTooShortError, "String length must be greater than 10");

        return NULL;

    }


    fp = fopen(filename, "w");

    bytes_copied = fputs(str, fp);

    fclose(fp);


    return PyLong_FromLong(bytes_copied);

}

After building the module with the new changes, you can test that your custom exception is working as expected by trying to write a string that is less than 10 characters in length:

>>> import fputs
>>> # Custom exception
>>> fputs.fputs("RP!", fp.fileno())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
fputs.StringTooShortError: String length must be greater than 10

When you try to write a string with fewer than 10 characters, your custom exception is raised with a message explaining what went wrong.

Defining Constants

There are cases where you’ll want to use or define constants in your Python C extension module. This is quite similar to how you defined custom exceptions in the previous section. You can define a new constant and add it to your module instance using PyModule_AddIntConstant():

PyMODINIT_FUNC PyInit_fputs(void) {
    /* Assign module value */
    PyObject *module = PyModule_Create(&fputsmodule);

    /* Add int constant by name */
    PyModule_AddIntConstant(module, "FPUTS_FLAG", 64);

    /* Define int macro */
    #define FPUTS_MACRO 256

    /* Add macro to module */
    PyModule_AddIntMacro(module, FPUTS_MACRO);

    return module;
}

This Python API function takes the following arguments:

  • The instance of your module
  • The name of the constant
  • The value of the constant

You can do the same for macros using PyModule_AddIntMacro():

PyMODINIT_FUNC PyInit_fputs(void) {
    /* Assign module value */
    PyObject *module = PyModule_Create(&fputsmodule);

    /* Add int constant by name */
    PyModule_AddIntConstant(module, "FPUTS_FLAG", 64);

    /* Define int macro */
    #define FPUTS_MACRO 256

    /* Add macro to module */
    PyModule_AddIntMacro(module, FPUTS_MACRO);

    return module;
}

This function takes the following arguments:

  • The instance of your module
  • The name of the macro that has already been defined

Note: If you want to add string constants or macros to your module, then you can use PyModule_AddStringConstant() and PyModule_AddStringMacro(), respectively.

Open up the Python interpreter to see if your constants and macros are working as expected:

>>> import fputs
>>> # Constants
>>> fputs.FPUTS_FLAG
64
>>> fputs.FPUTS_MACRO
256

Here, you can see that the constants are accessible from within the Python interpreter.

[Remove ads](/account/join/)
Testing Your Module

You can test your Python C extension module just as you would any other Python module. This can be demonstrated by writing a small test function for pytest:

import fputs

def test_copy_data():
    content_to_copy = "Real Python!"
    bytes_copied = fputs.fputs(content_to_copy, 'test_write.txt')

    with open('test_write.txt', 'r') as f:
        content_copied = f.read()

    assert content_copied == content_to_copy

In the test script above, you use fputs.fputs() to write the string "Real Python!" to an empty file named test_write.txt. Then, you read in the contents of this file and use an assert statement to compare it to what you had originally written.

You can run this test suite to make sure your module is working as expected:

$ pytest -q
test_fputs.py                                                 [100%]
1 passed in 0.03 seconds
Considering Alternatives

In this tutorial, you’ve built an interface for a C library function to understand how to write Python C extension modules. However, there are times when all you need to do is invoke some system calls or a few C library functions, and you want to avoid the overhead of writing two different languages. In these cases, you can use Python libraries such as ctypes or cffi.

These are Foreign Function libraries for Python that provide access to C library functions and data types. Though the community itself is divided as to which library is best, both have their benefits and drawbacks. In other words, either would make a good choice for any given project, but there are a few things to keep in mind when you need to decide between the two:

  • The ctypes library comes included in the Python standard library. This is very important if you want to avoid external dependencies. It allows you to write wrappers for other languages in Python.

  • The cffi library is not yet included in the standard library. This might be a dealbreaker for your particular project. In general, it’s more Pythonic in nature, but it doesn’t handle preprocessing for you.

For more information on these libraries, check out Extending Python With C Libraries and the “ctypes” Module and Interfacing Python and C: The CFFI Module.

Note: Apart from ctypes and cffi, there are various other tools available. For instance, you can also use swig and boost::Py.

Conclusion

In this tutorial, you’ve learned how to write a Python interface in the C programming language using the Python API. You wrote a Python wrapper for the fputs() C library function. You also added custom exceptions and constants to your module before building and testing it.

The Python API provides a host of features for writing complex Python interfaces in the C programming language. At the same time, libraries such as cffi or ctypes can lower the amount of overhead involved in writing Python C extension modules. Make sure you weigh all the factors before making a decision!

Why I use Java? Why not C#, JavaScript, or Python?

Why I use Java? Why not C#, JavaScript, or Python?

In this article, you'll see some reasons to I learn and use Java, why not C#, JavaScript, or Python? and why Java is one of the best programming language

But why Java? Why not C#, JavaScript, or Python?

Well… there were a few well-thought reasons behind this decision.

The top 3 programming languages in the world right now are Python, Java, and JavaScript. Sorry my C# friends, C# is not in the top 3 list. I’ll talk about C# later in this post.

Why not JavaScript?

Yes, we can do object-oriented programming with JavaScript. But let’s be real. Object-oriented programming with JavaScript is a bit messy. JavaScript classes are not real classes. They are syntactic sugar over constructor functions. Also, in JavaScript, we don’t have access modifiers like public and private. Yes, we can achieve them using other ways and I’ve demonstrated that in my Object-oriented Programming with JavaScript course. But still, JavaScript is not the best language for object-oriented programming.

Why not Python?

Python is a great language. I love it! It’s free of clutter and is simple to use. It also has better support for OOP features. So, why didn’t I choose Python? Because based on my research, Python is often used among people in the data science community, rather than professional software engineers.

Yes, you we use Python to build desktop and mobile apps as well as backends. However, Python is not the language of choice for building mobile or desktop apps. These days, the majority of people are building mobile apps using cross-platform solutions such as React Native or Flutter. Others do native development in Java (for Android) or Swift (for iOS). The same applies to building desktop applications with Python. Python is not very well known for that reason.

Why not C#?

C# and Java are very similar in terms of syntax and they both have great support for OOP features. So, why didn’t I choose C# given that I have several C# courses?

Well… I looked at different sources to see the popularity of Java vs C#. Google Trends is a great resource. As you saw earlier in the post, Java is way more popular than C#. Does it mean it’s a better language? Well, it depends on _how _we define “better”.

What is better? A Ferrari or a truck? It depends on what you want to do. Ferrari is a super-fast car but it’s useless if you want to use it to move house. Programming languages are the same. There is no such thing as the best programming language. Every language has pros and cons. C++ is well known for its speed. Python is popular for its simple and clean syntax as well as tons of resources for machine learning.

Just because Java is more popular, it doesn’t mean it’s a better language than C#. In my opinion, C# is a more feature-rich language but Java was marketed better.

C# and Java have been rivals since day one. Many of the features we’ve had in C# for a long time were introduced in Java years later. Some features don’t exist to this day! For example, in Java, we don’t have optional parameters which are very handy. We have to overload a method. Ugly! Jave interfaces are also bad.

I personally prefer C#. But as I said, Java has had better marketing and that’s why it’s always been more popular than C#.

Why Java?

So, I chose Java because it’s used more widely than C# amongst professional software engineers. There are more Java developers out there than C# developers. Most universities and colleges also tend to teach Java, rather than C#.

Now, all that aside, C# and Java are very similar in terms of the syntax. Recently I posted this tweet asking my students if this is Java or C# code?

The reality is I wrote this code in IntelliJ (a popular Java IDE). But the code is valid C# and Java code. Someone argued that this is an over-simplified example and shouldn’t be used as a basis for comparison. That is true. But my whole point is that if you understand this code, you can perfectly take my Data Structures or Design Patterns courses.

What You Should Take Away

In my opinion, Java in the programming world, is like the English language in the world we live in. If Italian or Hindi is the only language you speak, you’re probably not gonna get very far ahead.

If you understand English, you have access to tons of valuable resources. Whether you want to learn programming, or painting, or piano, if you “understand” English, you have tons of resources in front of you. You don’t need to be fluent in speaking English. All you need is to just understand it.

It’s the same story with Java. There are tons of great programming books written and these books use Java. If you simply understand the Java syntax, you can take advantage of these amazing resources. You don’t need to become a Java developer and let go of your favorite language, whether it is C# or JavaScript or Python or PHP.