VFP and .NET Interop
Can not create an instance of wwDotNetBridge
Gravatar is a globally recognized avatar based on your email address. Can not create an instance of wwDotNetBridge
  Naomi
  All
  Nov 23, 2016 @ 05:55am

I used wwDotNetBridge about a year or more ago with success (Windows 7 laptop). I am now using Windows 10 laptop and VS 2015. I downloaded the solution but I am unable to instantiate the bridge object. These lines of code always return -1

DECLARE Integer ClrCreateInstanceFrom IN WWC_CLR_HOSTDLL string, string, string@, integer@

	lcError = SPACE(2048)
	lnSize = 0
	lnDispHandle = ClrCreateInstanceFrom(FULLPATH("wwDotNetBridge.dll"),;
			"Westwind.WebConnection.wwDotNetBridge",@lcError,@lnSize)

	IF lnDispHandle < 1
	   this.SetError( "Unable to load Clr Instance. " + LEFT(lcError,lnSize) )
	   RETURN NULL 
	ENDIF
	
	---------------------------------------
	
	I've created a simple DLL that uses HttpClient. It has public class with 2 public methods that use some parameters passed by reference and also the last parameter has default value (it is not passed by reference). Anyway, I'm not sure what to do. I have a thread in UT on this problem. Thanks.
	
	These are my .NET Framework versions installed (from Control Panel):
	
	![](//support.west-wind.com/PostImages/2016/_4S80RWAP3.PNG)

Also, the error message is better after I re-started my laptop and shows "The assembly is built by a runtime newer than the currently loaded runtime, and cannot be loaded."

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Naomi
  Nov 23, 2016 @ 01:38pm

This error comes from the newer version of the bridge I downloaded today. I am now able to instantiate the version we have (older version), but I can not load assembly.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 24, 2016 @ 01:20am

You need to use .NET 4.0 as the runtime. When you create wwDotnetBridge use:

loBridge = CREATEOBJECT("wwDotnetBridge","V4")

or

loBridge = GetwwDotnetBridge("V4")

You can do this in your application startup code and that will force the V4 version to be loaded. Subsequent loads of wwDotnetBridge will then use whatever version was initially loaded.

Not sure why this isn't working - the latest version should be using .NET 4.0. Check your version of wwDotnetBridge.prg and it should have the version number set to:

cClrVersion = "v4.0.30319"

as shown here:

So it should default to that version. Is it possible you didn't recompile after updating the PRG files?

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 24, 2016 @ 02:10am

Rick,

I tried all versions using the version I've downloaded from GitHub. I tried V4, I tried without version, I tried using the highest version of .NET I have. I got different errors (for newer versions it was saying VFP9 needs to install that version), for V4 it gave me the error from my second reply.

Then I tried using older version of the bridge which was working in another project. When I run that project from VFP, the bridge loads, but the library is not being loaded.

I then tried it from the project I need to use it now. I can create an instance of the bridge object but it can not load my assembly (which is currently using version 4.5 of the framework and HttpClient class). I tried changing my project to target .NET 4.0 but then got too many errors.

I most likely will have to re-design my project to not use HttpClient as you suggested in UT.

Anyway, as I said, using the very latest version from GitHub doesn't work for me.

Also, I was unable to open that solution for the ClrHost project as it required some extra download and I answered 'No'. Now it doesn't ask me in VS, just doesn't load the project.

Also, Rick, would you be able to continue conversation in UT or you prefer this board?

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 24, 2016 @ 12:35pm

Are you using the files out of the Distribution folder from GitHub to grab the files from?

Try this:

Start a fresh instance of FoxPro in the folder where your wwDotnetBridge files live:

CD C:\Temp\wwDotnetBridge\Distribution
DO wwdotnetbridge
loBridge = CreateObject("wwDotNetBridge","V4")
? loBridge.GetDotnetVersion()

This works fine for me with a freshly cloned copy from Github.

You do need to have .NET 4.0 or later installed for any of this to work. I think "V2" no longer works due to the new recompiled version that uses .NET 4.0 features so make sure that the V4 version is used.

Also make very sure you're not loading a copy of wwDotnetBridge.prg from a different location. From what you describe it sounds like an older version is loading and trying to load "V2" explicitly. You can step through the code to check.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 24, 2016 @ 12:54pm

I've been stepping through the code. From this page https://west-wind.com/wwDotnetBridge.aspx there is a link Get the code from

You can download a complete Zip (so this one I downloaded and extracted). That zip has a folder called Examples. So, from that examples folder I was trying ResizeImage example. And it doesn't work for me, it generates that error.

I just re-tried using the Distribution folder and your suggested code. I got the error

Program Error Cancel Suspend Ignore Help Unable to load wwDotNetBridge: Unable to load Clr Instance.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 24, 2016 @ 01:42pm

The files in the examples folder should be fine.

I think the problem most likely is that the DLLs are blocked.

Unfortunately the error returned for this by Windows is not descriptive so no way to provide a cleaner error message.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 25, 2016 @ 04:06am

Thanks, that solved the problem with the error. Do you think I will be able to load my 4.5 dll with that version of the bridge?

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 25, 2016 @ 02:25pm

Yes.

.NET 4.5 IS .NET 4.0 with only a different build number. ie. all 4.x versions of .NET qualify as 4.0 with additional features (forward compatible).

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 26, 2016 @ 10:43am

I am now getting the following error message (the same code works fine from my .NET test):

Could not load file or assembly 'System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

Do I need to place that dll into the same folder as my dll ?

UPDATE. After I placed both dlls (NewtonJson and Net.Http.Formatting) into the same folder as my main dll, I am now getting bad request. Fiddler doesn't show the proper JSON being passed or returned.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Naomi
  Nov 26, 2016 @ 11:39am

Actually, now I am getting the same error from .NET as well - Bad request. The JSON being send now is different than what I was sending before which is strange. It was working fine last Tuesday when I tested it.

I will need to re-write the whole thing 😦

I also noticed that the content is being send as text/plain even though it was supposed to be send as json (and last time I tested it was send correctly).

I have the following code

client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.BaseAddress = new Uri(tcHost);

        Why would it send now as plain text?
Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Naomi
  Nov 26, 2016 @ 01:47pm

I've tried various things but it is still being sent as text/plain and I believe it's the problem.

Last attempt was

private void SetRequestHeaders(string tcHost, string tcUserName, string tcPassword, int tnTimeout)
        {
           // client.DefaultRequestHeaders.Accept.Clear();
            client.BaseAddress = new Uri(tcHost);
            client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");

            client.DefaultRequestHeaders.Authorization =
                        new AuthenticationHeaderValue(
        "Basic",
        Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
                string.Format("{0}:{1}", tcUserName, tcPassword))));

            //  client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue() { MaxAge = TimeSpan.Zero };
            client.Timeout = TimeSpan.FromSeconds(tnTimeout);
        }

which didn't help. I am having hard time trying to convert my previously working code to use HttpWebRequest class. The best sample I found so far of using that class is https://www.codeproject.com/articles/6554/how-to-use-httpwebrequest-and-httpwebresponse-in-n which I will need to adapt to send and receive json.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 27, 2016 @ 08:43pm

I have no idea what you're asking...

If you have a problem with your .NET code please post a separate question.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 28, 2016 @ 02:59am

I asked a separate question in the .NET forum (as well as in UT on your reply to me).

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 28, 2016 @ 11:48pm

Thanks - looks like you figured it out.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 29, 2016 @ 04:06am

I tried testing my dll using the wwDotNetBridge. In my program I have at the end

release oNetBridge and oNetBridge = null

However, if I run my test program twice I'm getting attached message

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 29, 2016 @ 04:52pm

That's a .NET error - you're probably not releasing some instance of an object in that code.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 29, 2016 @ 08:52pm

I'm going to change my dll again - yesterday I changed everything to use static class and methods and static properties because I wanted to use declare in VFP. But I think I hit a road block unless you know if it can be done. My methods return strings as parameters passed by reference.

I am unable to make that to work from VFP using DllExport.

I briefly tried using that dll and InvokeStaticMethod from the bridge, but could not make it work.

So, I will have to switch back to non-static methods and class.

Also looks like I can not use WestwindUtilities because I don't see how to implement my scenario of sending one json and getting back a different json object.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Nov 30, 2016 @ 03:36am

I fixed that problem after some changes in my library. However, when I'm testing the debug version from VFP I have to close VFP in order to re-build my dll. Issuing clear all and clear dlls doesn't help.

But I am able to run my test VFP program that uses bridge several times without an error.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Naomi
  Nov 30, 2016 @ 10:52am

My colleague raises the following concerns - do you know the answer:

I don’t know enough about wwDotNetBridge yet to determine how much overhead/performance impact it will be. And how does the ClrLoader.dll (which loads the .NET runtime on first access) and wwDotNetBridge.dll behave in the multiple instance environment of our VFP dll?

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Nov 30, 2016 @ 04:22pm

However, when I'm testing the debug version from VFP I have to close VFP in order to re-build my dll. Issuing clear all and clear dlls doesn't help.

Yes that's simply the way it is. .NET cannot unload assemblies or DLLs once loaded and it's not really possible to unload .NET once it's been loaded. Same is true for plain COM interop.

I don’t know enough about wwDotNetBridge yet to determine how much overhead/performance impact it will be. And how does the ClrLoader.dll (which loads the .NET runtime on first access) and wwDotNetBridge.dll behave in the multiple instance environment of our VFP dll?

There's very little overhead if you compare to using standard .NET Interop. Most of the time you access components the same way you do with direct COM Interop so the overhead is the same. When using FoxPro the overhead of the indirect Reflection calls using things like InvokeMethod() or GetProperty() are almost negliable due to the overhead of the interop calls in the fist place.

The restrictions on wwDotnetBridge are basically the same as if you used COM interop natively. wwDotnetBridge just provides a separate bootstrapper for the .NET runtime so you don't have to use COM registered components but rather can access any .NET component. But other than that it's the same as if you were using COM interop.

Note you can also use wwDotnetBridge with plain .NET COM Interop components instantiated with CREATEOBJECT() if use the lUseCom parameter when you instantiate it via CREATEOBJECT("wwdotnetBridge,"v4",.t.). When you do this the custom runntime loader is bypassed but you still get all the rest of the features. If you do this though, wwDotnetBridge needs to be registered as a COM object though which defeats one of the big reasons on why to use it in the first place (namely no COM registrations required).

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Naomi
  Rick Strahl
  Dec 1, 2016 @ 02:11am

Thanks a lot. I hope we're going to use the bridge and the library now as is.

In the future we're going to switch to C# dll, so this should be a temporary solution anyway.

Gravatar is a globally recognized avatar based on your email address. re: Can not create an instance of wwDotNetBridge
  Rick Strahl
  Naomi
  Dec 1, 2016 @ 12:25pm

Yeah but you may still want to use wwDotnetBridge to call that DLL to avoid COM registration and having to export your interfaces. There are lots of things you can't do with regular COM interop, which is why this class exists, although if you build your own you can usually work around the stuff that doesn't work.

+++ Rick ---

© 1996-2024