Hacker News new | past | comments | ask | show | jobs | submit login
Writing a D Wrapper for a C Library (dlang.org)
73 points by ingve 5 months ago | hide | past | web | favorite | 14 comments

As someone who never had a problem with it, I would be interested in learning what drew you away from Ada to D.

It seems like this is an unsafe and also leaky way of wrapping the API? Copying an URIWithoutFinalise seems to allocate a new C pointer and never free it, and it seems the URI type can be copied without creating a new pointer, leading to double frees! Maybe I'm misunderstanding D here, but shouldn't the new/copy/free all happen in a single object similar to the C++ rule-of-three?

If that's not possible, isn't it typical to give the pointers an "identity" (store them in a class) to provide a GC-language with safety when wrapping a C API that seems to use a more affine/linear ownership system?

It seems to be undermining D's claims of safety if the "official" (widely published on the official blog) way to wrap C APIs is unsafe.

(Plus, at least the example code listings for the mixins, failure (returning NULL) of the C calls isn't checked.)

Yes, you are reading the D incorrectly. `URIWithoutFinalise` has no post-blit constructor (D does not have copy constructors) and thus does nothing on copy. It does have a method called `dup` that returns a `URI`(WithFinalization), but this is not called on copy.

`URI` cannot be copied because the post-blit constructor is disabled. The default constructor is also disabled, so a "null" URI couldn't be created either.

You'll get no argument from me about not checking for failure though. Some asserts at least would be a good idea there.

Oh, awesome! Thanks!

Most of wrappers in D are actually very thin wrappers over C bindings, focusing on C interop rather than trying to push D objects through. But to be honest, no matter what you do, as soon as you begin to interface with C, you are throwing safety out of the window anyway.

There's the unsafety inherent to C, with the risks of bugs in the underlying library, and there's unsafety caused by misusing the API. Safe languages often provide enough power to make the latter impossible, for a C API that fits standard patterns like "new, some operations, free", or even reference counting. I think D, via classes, is one of these languages, with enough power to make the wrapper itself safe (that is, impossible to misuse the API), at least for basic stuff like construction and destruction.

I think the use case for WithoutFinalise is for working with shared pointers (judging by the text).

In that case, if you're going to copy the pointer, you don't want to then free the memory, since you no longer know whether all copies have finished being used.

Having said, that, some kind of reference counting might be a safer strategy. It depends a bit on what the client code is up to.

If that's the case, I don't think it should be calling raptor_uri_copy, which allocates a whole new URI object (not just changing some reference counts). It could instead provide a "URI full_copy()" method that better models how the C API works.

Even then, it still isn't safe, because D doesn't (yet) seem to have the tools required to tie this sort of non-owning reference to the owning object, to avoid the dangling pointer problem mentioned in the article.

I'm not a D expert, but I think the raptor_uri_copy is called in dup() method of URIWithoutFinalize/URI, which is essentially the full_copy() method. The code says only URIWithoutFinalize() is shallow-copyable, and URIWithFinalize is not (see @disable this(this);).

> if the "official" (wildly published on the official blog) way to wrap C APIs is unsafe.

It‘s clearly far from “official” recommendation. It’s more “an experience of one user” that can also be scrutinized.

I think that's nice in theory, but not true in practice. If someone new to D comes across this post, their assumption will almost certainly be that this post comes from a place of deep expertise and represents some form of best practice ("the language owners approved it").

(Also, just to be clear, I had a typo before: wildly -> widely.)

Really, no. This is official:


A blog entry with an experience of one user is just a blog entry with an experience of one user, and has exactly that much relevance, no matter where it is hosted. Where do you see that it was "peer reviewed" or that it is somehow or somewhere claimed to be a "recommended way" for anything at all?

You surely can't interpret your own belief (which is wrong) and claim that it's an "official" recommendation for "the way" something is to be done "in general" when writing D. It is just your own belief. You can only claim that you have subjectively and personally got that impression (that the post is more relevant than it is) but nothing more.

It's written on the main D language website - not just some random persons blog?

It actually is almost a such. The category in which it appeared is "Guest Posts", that is, in the category where:

"Now and again, we’ll publish a post in which D users talk of their experiences with D, not about specific projects, but about the language itself. They’ll tell of things like their favorite features, why they use it, how it has changed the way they write code, or anything they’d like to say that expresses how they feel about programming in D."


Moreover, the article starts with "I initially started my research project using the Ada 2012 programming language (see my article “Experiences on Writing Ada Bindings for a C Library” in Ada User Journal, Volume 39, Number 1, March 2018)." "After some unsatisfying experiments with Java and Python, I settled on the D programming language."

It's obviously a D language beginner writing about his experiences. Showing his code. Which worked for him. Nothing wrong with that.

Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact