mono / Embeddinator-4000

Tools to turn .NET libraries into native libraries that can be consumed on Android, iOS, Mac, Linux and other platforms.
MIT License
758 stars 95 forks source link

is System.Net.Http.HttpClient not supported by Embeddinator-4000 ? #685

Closed dcordero closed 5 years ago

dcordero commented 6 years ago

Steps to Reproduce

  1. Run objcgen to generate a objc framework from a dll which make use of Sytem.Net.Http.HttpClient

Expected Behavior

The objc framework is generated

Actual Behavior

The generated output folder is empty, and I see the following error in the logs: [...] Generating binding code... error EM0009: The feature Converting type System.Net.Http.HttpClient to mono code is not currently supported by the tool Debug Log [...]

Environment

Embeddinator-4000 v0.1 (0.4: 7664197)
VincentDondain commented 6 years ago

Please include a test case (to reproduce, the dll you used), your full build logs, crash reports (if any) and all your version information.

dcordero commented 6 years ago

A project reproducing this issue can be found in the following repo:

https://github.com/dcordero/EmbeddinatorPlayground

Build logs:

~/.nuget/packages/embeddinator-4000/0.4.0/tools/objcgen EmbeddinatorPlayground/bin/Debug/netstandard2.0/EmbeddinatorPlayground.dll --target=framework --platform=iOS --outdir=output -c --debug
Symbol file /Users/dcordero/.nuget/packages/embeddinator-4000/0.4.0/tools/IKVM.Reflection.pdb doesn't match image /Users/dcordero/.nuget/packages/embeddinator-4000/0.4.0/tools/IKVM.Reflection.dll
Parsing assemblies...
    Parsed 'EmbeddinatorPlayground/bin/Debug/netstandard2.0/EmbeddinatorPlayground.dll'
Processing assemblies...
    1 types found
Generating binding code...
error EM0009: The feature `Converting type System.Net.Http.HttpClient to mono code` is not currently supported by the tool
Debug Log:
Processing: 1 assemblies
Processing Assembly: EmbeddinatorPlayground
Processing Type: EmbeddinatorPlayground_MyDummyClass
TypeMapper Register: System.Void .ctor(System.Net.Http.HttpClient) initWithClient:
TypeMapper Register: System.Void FetchData() fetchData
Begin Generator
Generating Assembly: EmbeddinatorPlayground
Generating Type: EmbeddinatorPlayground_MyDummyClass
rothomp3 commented 6 years ago

I'm experiencing a different, but related problem. System.Net.Http seems to work fine with an iOS library embeddinated, but I'm having trouble with Android. When I attempt to make a request, I get a NameResolutionFailed exception, and if I specify the IP address explicitly, instead I get Error: ConnectFailure (mono-io-layer-error (10013)). It seems like it's working, but for some reason can't actually access the network hardware. I've tried using modernhttpclient-updated and referencing OkHttp as a dependency in the Android project, but I get the exact same results.

equinox2k commented 6 years ago

Have you added internet permissions to the android XML file ?

Pete

On Aug 30, 2018, at 1:12 PM, Robert Thompson notifications@github.com<mailto:notifications@github.com> wrote:

I'm experiencing a different, but related problem. System.Net.Http seems to work fine with an iOS library embeddinated, but I'm having trouble with Android. When I attempt to make a request, I get a NameResolutionFailed exception, and if I specify the IP address explicitly, instead I get Error: ConnectFailure (mono-io-layer-error (10013)). It seems like it's working, but for some reason can't actually access the network hardware. I've tried using modernhttpclient-updated and referencing OkHttp as a dependency in the Android project, but I get the exact same results.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/mono/Embeddinator-4000/issues/685#issuecomment-417451822, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAoCQ4ojLlMxzjyETotVLKAxLuztT1VQks5uWEchgaJpZM4VQ_hB.

rothomp3 commented 6 years ago

Hah, I bet that's it, I'll check as soon as I get a chance. I admit I'm primarily an iOS developer, so this slipped past me completely.

007vel commented 5 years ago

Have you added internet permissions to the android XML file ? Pete On Aug 30, 2018, at 1:12 PM, Robert Thompson notifications@github.com<mailto:notifications@github.com> wrote: I'm experiencing a different, but related problem. System.Net.Http seems to work fine with an iOS library embeddinated, but I'm having trouble with Android. When I attempt to make a request, I get a NameResolutionFailed exception, and if I specify the IP address explicitly, instead I get Error: ConnectFailure (mono-io-layer-error (10013)). It seems like it's working, but for some reason can't actually access the network hardware. I've tried using modernhttpclient-updated and referencing OkHttp as a dependency in the Android project, but I get the exact same results. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub<#685 (comment)>, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAoCQ4ojLlMxzjyETotVLKAxLuztT1VQks5uWEchgaJpZM4VQ_hB.

worked for me.

spouliot commented 5 years ago

This is a question of expectations. How would you use the generated API ? i.e. HttpClient does not exists in Objective-C.

Also HttpClient is not part of the code you provide to e4k (EmbeddinatorPlayground.dll).

In theory we could bind the type from the BCL but that would mean, recursively, binding most of mscorlib, System, System.Net, System.Net.Http... assemblies and a gigantic output library.

To avoid this bloating situation you better define a contract type, e.g. a subset of HttpClient, inside your code and use this. That way e4k will create binding (out your new type) and you'll limit the bloat by deciding what is exposed in your library, e.g.

public class ManagedHttpClient {
   HttpClient c;
   public ManagedHttpClient ()
   {
      c = new HttpClient ();
   }
   // re-expose what needs to be available inside the library
}

Another alternative is not to expose HttpClient at all - and just add properties (in your existing type) to adjust the properties of the instance you created (in the managed constructor).

dcordero commented 5 years ago

Hi @spouliot,

The project linked to reproduce the issue, that means EmbeddinatorPlayground, does make use of HttpClient.

Also, as you can see in that code, the use of HttpClient is private to the framework and it is not part of the public API. As a result of that, to the question "How would you use the generated API?" the response is... I will not use it, I can not even do it, it is private.
As a user of the framework I will make use of its public API, and I do not care at all about the internal implementation details of its network layer.

In the dummy example implemented by EmbeddinatorPlayground, that means calling the public method FetchData and expecting an output OK or KO in the console depending on the result.

spouliot commented 5 years ago

the use of HttpClient is private to the framework and it is not part of the public API

That's exactly the problem :)

https://github.com/dcordero/EmbeddinatorPlayground/blob/master/EmbeddinatorPlayground/MyDummyClass.cs#L10 makes HttpClient public since the type and the constructor are both public - which is what e4k generates bindings on.

Make the constructor private (or remove the HttpClient argument of the costructor) and it should build fine.