DPP: Linker issue with functions implemented in C header files
Petar
Petar
Tue Feb 18 10:23:22 UTC 2020
On Tuesday, 18 February 2020 at 09:20:08 UTC, Andre Pany wrote:
>
> Hi Petar,
Hi Andre, I'm happy to help :)
> thank you very much for the explanation and the code sample.
> Filling the az_span anonymous member was the tricky part,
> I thought it would be not possible to do so, but you showed me
> the trick.
I wouldn't call it a trick, I was using standard struct literal
initialization (the very syntax that DIP1031 proposes to
deprecate).
For example:
struct Inner { int x, y; }
struct Outer { Inner inner; }
// You can initialize Outer in various ways:
// 1)
auto o1 = Outer(Inner(1, 2));
// 2)
Outer o2 = { inner: Inner(1, 2) };
// 3)
Outer o3 = { Inner(1, 2) };
// 4)
Outer o4 = { inner: { x: 1, y: 2} };
// 5)
Outer o5 = { { x: 1, y: 2} };
// 6)
Outer o6;
o6.inner.x = 1;
o6.inner.y = 1;
For POD (plain old data) struct like that, all six variants are
equivalent (of course there more possible variations).
Since there's no `private` protection modifier in C, the only
thing C library authors can do is make it inconvenient to access
struct fields (by prefixing them with underscores), but they
can't really prevent it.
For example, without this syntax, in pure C you can initialize a
span like this:
char my_string[] = "Hey";
az_span span;
span._internal.ptr = my_string;
span._internal.length = sizeof(my_string) - 1;
span._internal.capacity = sizeof(my_string) - 1;
And with almost the same syntax you can do this in D:
string my_string = "Hey";
az_span span;
span._internal.ptr = cast(ubyte*)my_string.ptr; // note: I think
this should be safe, because of [1]
span._internal.length = my_string.length;
span._internal.capacity = my_string.length;
It's just that that author wanted to prevent accidental bugs by
pushing you to use the inline helper functions or macros (which
are technically not needed).
[1]:
https://github.com/Azure/azure-sdk-for-c/blob/25f8a0228e5f250c02e389f19d88c064c93959c1/sdk/core/core/inc/az_span.h#L22
> I will do it like you have proposed but had also already created
> a ticket for the Azure SDK developer:
> https://github.com/Azure/azure-sdk-for-c/issues/359
> There should be a more convenient way to fill a az_span
> structure.
To be honest, I don't think the authors will agree to change
this, as putting inline functions in headers files is a pretty
common practice in both C and C++.
There are two benefits to that:
1) Potentially better performance, because the code is easier to
inline
2) It's possible to provide header-only libraries (not the case
here), that don't require build steps.
> For reference, here is my dockerfile which does the DPP call
> and linking:
Cool, I'll check it later!
> ``` dockerfile
> FROM dlang2/ldc-ubuntu:1.20.0 as ldc
>
> RUN apt-get install -y git libssl-dev uuid-dev
> libcurl4-openssl-dev curl
>
> RUN curl -OL
> https://cmake.org/files/v3.12/cmake-3.12.4-Linux-x86_64.sh \
> && mkdir /opt/cmake \
> && sh /cmake-3.12.4-Linux-x86_64.sh --prefix=/opt/cmake
> --skip-license \
> && ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
>
> RUN git clone https://github.com/Azure/azure-sdk-for-c.git \
> && cd azure-sdk-for-c \
> && git submodule update --init --recursive
>
> RUN cd azure-sdk-for-c \
> && mkdir build \
> && cd build \
> && cmake ../ \
> && make
>
> RUN apt-get install -y clang-9 libclang-9-dev
> RUN ln -s /usr/bin/clang-9 /usr/bin/clang
> COPY az_storage_blobs.dpp /tmp/
>
> RUN DFLAGS="-L=-L/usr/lib/llvm-9/lib/" dub run dpp -- --help
>
> RUN DFLAGS="-L=-L/usr/lib/llvm-9/lib/" dub run dpp --
> /tmp/az_storage_blobs.dpp \
> --include-path /azure-sdk-for-c/sdk/core/core/inc \
> --include-path /azure-sdk-for-c/sdk/core/core/internal \
> --include-path /azure-sdk-for-c/sdk/storage/blobs/inc \
> --include-path
> /azure-sdk-for-c/sdk/transport_policies/curl/inc \
> --preprocess-only
>
> ADD blobs_client_example.d /tmp/blobs_client_example.d
> RUN ldc2 /tmp/blobs_client_example.d /tmp/az_storage_blobs.d \
> /azure-sdk-for-c/build/sdk/core/core/libaz_core.a \
>
> /azure-sdk-for-c/build/sdk/storage/blobs/libaz_storage_blobs.a \
>
> /azure-sdk-for-c/build/sdk/transport_policies/curl/libaz_curl.a
> \
> -of=/tmp/app
> ```
>
> Kind regards
> André
Cheers,
Petar
More information about the Digitalmars-d-learn
mailing list