How to import C-files (.h/.c) in Oxygene?

what do you mean exactly?

As I said, cant build because of 800 Errors :frowning:

ok, let me look into that OH WAIT, i can’t because i don’t know what they are!

Ok, do you want me to send you the Project or to declar which type o errors?

Well, there 800 Syntax error, dont know still what do you mean with “what they are”?

but here the Project:

train-master.zip (9.6 MB)

So there’s some confusion here. There’s no train based script yet for importing headers for Island, only for Toffee.

To currently use C based libraries there are two options:

  • Directly call header importer and create an fx/a pair that way
  • Use dllimport (only works for dll/so files)

Dll import is simple:

[DllImport('Kernel32.dll'), CallingConvention(CallingConvention.Stdcall)]
class method Beep(aFreq, aSeq: Integer);

Header Importer is trickier. The goal is to make a train script to make this easier but there isn’t one yet. The first step for HI is to create an import definition, this is a json file like:

{
  "TargetString": "i686-pc-windows-msvc",
  "Version": "3.18",
  "SDKVersionString": "3.18",
  "Imports": [
    {
      "Name": "sqlite3",
      "ForceNamespace": "sqlite3",
      "Files": [ "sqlite3.h" ],
      "IndirectFiles": [],
      "DepLibs": [ "sqlite3.lib" ],
      "ImportDefs": [
        { "Name": "_TryEnterCriticalSection@4", "Library": "Kernel32.dll" },
        { "Name": "_AreFileApisANSI@0", "Library": "Kernel32.dll" },
        { "Name": "_DeleteFileA@4", "Library": "Kernel32.dll" },
        { "Name": "_FormatMessageA@28", "Library": "Kernel32.dll" },
        { "Name": "_FormatMessageW@28", "Library": "Kernel32.dll" },
        { "Name": "_FreeLibrary@4", "Library": "Kernel32.dll" },
        { "Name": "_GetDiskFreeSpaceA@20", "Library": "Kernel32.dll" },
        { "Name": "_GetDiskFreeSpaceW@20", "Library": "Kernel32.dll" },
        { "Name": "_GetFileAttributesA@4", "Library": "Kernel32.dll" },
        { "Name": "_GetFileAttributesExW@12", "Library": "Kernel32.dll" },
        { "Name": "_GetFileSize@8", "Library": "Kernel32.dll" },
        { "Name": "_GetFullPathNameA@16", "Library": "Kernel32.dll" },
        { "Name": "_GetSystemTimeAsFileTime@4", "Library": "Kernel32.dll" },
        { "Name": "_GetTempPathA@8", "Library": "Kernel32.dll" },
        { "Name": "_GetTempPathW@8", "Library": "Kernel32.dll" },
        { "Name": "_HeapCreate@12", "Library": "Kernel32.dll" },
        { "Name": "_HeapDestroy@4", "Library": "Kernel32.dll" },
        { "Name": "_HeapReAlloc@16", "Library": "Kernel32.dll" },
        { "Name": "_HeapSize@12", "Library": "Kernel32.dll" },
        { "Name": "_HeapValidate@12", "Library": "Kernel32.dll" },
        { "Name": "_HeapCompact@8", "Library": "Kernel32.dll" },
        { "Name": "_LoadLibraryA@4", "Library": "Kernel32.dll" },
        { "Name": "_LoadLibraryW@4", "Library": "Kernel32.dll" },
        { "Name": "_LocalFree@4", "Library": "Kernel32.dll" },
        { "Name": "_LockFile@20", "Library": "Kernel32.dll" },
        { "Name": "_LockFileEx@24", "Library": "Kernel32.dll" },
        { "Name": "_QueryPerformanceCounter@4", "Library": "Kernel32.dll" },
        { "Name": "_SystemTimeToFileTime@8", "Library": "Kernel32.dll" },
        { "Name": "_UnlockFile@20", "Library": "Kernel32.dll" },
        { "Name": "_UnlockFileEx@20", "Library": "Kernel32.dll" },
        { "Name": "_WaitForSingleObjectEx@12", "Library": "Kernel32.dll" },
        { "Name": "_OutputDebugStringA@4", "Library": "Kernel32.dll" },
        { "Name": "_OutputDebugStringW@4", "Library": "Kernel32.dll" },
        { "Name": "_FlushViewOfFile@8", "Library": "Kernel32.dll" }
      ]
    }
  ],
  "Platform": "Windows"
}

There are a few important things here: Platform has to match the target platform (Windows in my case). TargetString has to match the targets target string (“TargetString”: “i686-pc-windows-msvc” for Windows 32bits).

Version is the file version (in a.b.c.d format) SDKVersionString is shown in the IDE (can be anything)

An import file can contain multiple imports, the same has just one, named “sqlite3”, ForceNamespace defines the namespace this is going to be defined in, “Files” contains the files to import from. Indirect files are the files that need to be imported, but shouldn’t be loaded directly, instead they are included indirectly by the files in “Files” via #include. Types defined in a file not mentioned in these two arrays are not imported, they are ignored. DepLibs contains the dependencies for the linker, ie the .o/.a/lib file.

The last bit here is the import defs. These are dll imports by this library that the compiler doesn’t know about, they define which symbol is defined in which dll, for example:
{ “Name”: “_TryEnterCriticalSection@4”, “Library”: “Kernel32.dll” },

TryEnterCriticalSection is defined in Kernel32.

Note: We don’t officially support custom imports via Header importer yet.

Thanks a lot carlo, but I also have then to mention something here^^

  1. I suggest you then, to take, at least for the current Moment, this line of the page out:
    Of course any other custom, third party or open source C APIs can be imported using HeaderImporter
    src: https://docs.elementscompiler.com/Platforms/Island/Windows/
    could be confusing otherwise :stuck_out_tongue:

  2. Am I able to just call 1 .h file in Oxygene via DllImport, even if it isnt a standardCall?

1: yes, it’s a work in progress. HI as it is isn’t very user friendly, hence what I Said.
2: You don’t call “h” files, you call dlls. That only works if you have a dll ofc, else you have to use header importer.

1 Like

Well, quite obviously i know how to pull the Train master branch, myself. It’s also safe too assume that it builds fine, for me, given that we’d not publish a project with 800 compile errors that we know about and call it good.

so i ask again: with what errors does it fail for you?

@ck @mh You meant I can directly include a C header file in Island project? Like, I can directly include Google TensorFlow C Api header file?

You cannot simply just add the C headerfile straight to the project, but you can create an Import Project, as described at Import Projects to generate a .fx file from the header, and you can then reference that .fx file (or the project, as project reference), like you would any other reference.

Let us know if you need any help creating the import. You can find some other imports, for reference, at GitHub - remobjects/recipes: Contains recipes for importing known open source projects — and once you have Tensorflow working, it might be cool to include that there.

This import works for me, if I coy the project into an folder Elements within the downloaded zip/tar.gz file:

Elements.zip (20.9 KB)

so the structure is like such:

in vNext (not today’s upcoming build), I’ve extended support for Import projects (and ay project really) to be a blessing to pull in the binaries remotely, so an import project can build w/o having to have all the binaries gathered in the right places manually. eg:

    <ImportLinkLibrary Include=".\lib\libtensorflow.dylib">
      <Remote>https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-darwin-x86_64-1.15.0.tar.gz</Remote>
      <Target>Island.macOS</Target>
    </ImportLinkLibrary>
    <ImportLinkLibrary Include=".\lib\tensorflow.dll">
      <Remote>https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.15.0.zip</Remote>
      <Target>Island.Windows</Target>
    </ImportLinkLibrary>
    <ImportLinkLibrary Include=".\lib\libtensorflow.so">
      <Remote>https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-linux-x86_64-1.15.0.tar.gz</Remote>
      <Target>Island.Linux</Target>
    </ImportLinkLibrary>

Thank you. But the generated TensorFlow.fx doesn’t seem to work. The architecture is x86_64, but TensorFlow.fx ended up in i386.

Also I created an Windows Island Console, added TensorFlow.fx (withOUT calling any tensor flow Apis, just reference it), it won’t compile.

Also, is there a converter to convert c header to oxygene .pas file?

Ah yes, the import project doesnt know the actual architecture of the .dll, so the project will “build” for i386 and x64, even though the former might not be supported. add an <Architecture>x86_64</Architecture> tag to the project, like such:

  <PropertyGroup Condition=" '$(Target)' == 'Island.Windows' ">
    <Mode>Island</Mode>
    <SubMode>Windows</SubMode>
    <Architecture>x86_64</Architecture>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Target)' == 'Island.Linux' ">
    <Mode>Island</Mode>
    <SubMode>Windows</SubMode>
    <Architecture>x86_64</Architecture>
  </PropertyGroup>

What’s the error?

No, that’s what the Import project is for; we don’t use Delphi-style manual header units (although you can of course manually create imports in code, if needed, in that fashion. But getting the Import project working is the better solution.

One minor issue im seeing is that the .dll isn;'t being copied next to the .fx, even if CopyLocal is set; I’ll investigate and fix that now.

@mh Thank you for the diligent support. Appreciate it!

I followed your advice, and build a x86_64 TensorFlow.fx. But still I got errors (see the figure). Any advice?

Yeah, I’m at the same error now after some fixes to how EBuild copies the .dll. I’m afraid this one’s beyond my pay-grade and Carlo will need to answer it on Monday :(.

Workaround for now, reference the .lib in the import project, instead of the .dll, and then copy the .dll over next to your final exe manually.

    <ImportLinkLibrary Include=".\lib\tensorflow.lib">
      <Remote>https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.15.0.zip</Remote>
      <Private>True</Private>
      <Target>Island.Windows</Target>
    </ImportLinkLibrary>
1 Like

in vNext, this will work:

    <ImportLinkLibrary Include=".\lib\tensorflow.lib">
      <Remote>https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.15.0.zip</Remote>
      <Private>True</Private>
      <Target>Island.Windows</Target>
    </ImportLinkLibrary>
    <ImportCopyLocal Include=".\lib\tensorflow.dll">
      <Remote>https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.15.0.zip</Remote>
      <Private>True</Private>
      <Target>Island.Windows</Target>
    </ImportCopyLocal>

I am sorry, but what is “vNext”?

The next version/build of Elements.