I'm creating a wrapper from loading 32-bit unmanaged dll to execute in 64-bit environment. so my approach used this LegacyWrapper
[LegacyDllImport("ste.dll")]
public interface INativeMethods : IDisposable
{
[LegacyDllMethod(CallingConvention = CallingConvention.Winapi)]
IIntPtr ste_init_with_environment_info(string dirLocation, string language);
}
I'm calling this method as below
public IWrapperConfig Configuration
{
get
{
return _configuration ??= WrapperConfigBuilder.Create().TargetArchitecture(TargetArchitecture.X86).Build();
}
}
using var client = WrapperProxyFactory<INativeMethods>.GetInstance(Configuration);
_steHandle = client.ste_init_with_environment_info(steHomeDirectory, SystemProperties());
it seems works without exception but. When I call the function, as a result, I'm getting 0x0000000000000000 which should be something like 0x0186ad58 what causes the issue?
UPDATE
when I see the source code of LagacyWrapper see the serialization and deserialization as below using System.Runtime.Serialization.IFormatter
public void SendCallRequest(CallData callData)
{
_formatter.Serialize(_pipe, callData);
}
public CallResult ReceiveCallResponse()
{
CallResult callResult = (CallResult)_formatter.Deserialize(_pipe);
if (callResult.Exception != null)
{
throw callResult.Exception;
}
return callResult;
}
I'm not very familiar with LegacyWrapper, so this is based on conjecture.
From the blogpost introducing Legacy wrapper:
Since we can’t load 32bit code into our 64bit process, the idea is to create a separate executable for this task. It would somehow load a library, invoke a specific function and pass the results back to the caller.
Since your library runs in another process, returning a pointer to memory will probably not work. As far as I know there is no general way to know how much valid memory a pointer points to, so how would the wrapper know how much memory to copy? This might be possible to solve for some special cases, but I cannot find any documentation about the details of the serialization-process.
You might be able to define that the pointer should be marshalled to a structure. Otherwise you might want to post an issue at the legacyWrapper project page, to clarify the documentation if nothing else.
I have this snippet on Windows (VS2017 Community) on Unity 5.6:
public static void setClipboardStr(string str)
{
try
{
if (Clipboard.ContainsText())
{
// ...doesn't matter if true or false -
// from here on, I can't copy+paste inside
// the game or outside until I close the app.
// If I had an error instead of try/catch or
// check if it contains text, the error will
// remain UNTIL I REBOOT (beyond the app closing).
}
}
catch(Exception ex)
{
Debug.LogError(ex);
}
}
Whenever I use Clipboard in any form, even when checking if it's text or not, it destroys the clipboard until I close the app. Now, is this a Unity bug? VS bug? Is there something I'm not understanding? What should I use, instead?
Clipboard.ContainsText is from the System.Windows.Forms namespace. These are not supported in Unity. One would be lucky to get it to compile and extremely luck to get work properly since Unity uses Mono. Also, this is not portable so don't use anything from this namespace in Unity.
What should I use, instead?
Write to clipboard:
GUIUtility.systemCopyBuffer = "Hello";
Read from clipboard:
string clipBoard = GUIUtility.systemCopyBuffer;
This should work. If not, you can implement your own clipboard API from scratch using their C++ API. You do have to do this for each platform.
OK, so I have the C# DLL method:
public void DeletePublisher(string strName)
{
try
{
if (_PublisherData.PublisherDictionary.ContainsKey(strName))
_PublisherData.PublisherDictionary.Remove(strName);
}
catch (Exception ex)
{
SimpleLog.Log(ex);
}
}
It works fine. If there is a exception it is detected and added to the log.
At the moment, the above is called via MFC in my C++ project using a wrapper:
bool CMSATools::DeletePublisher(CString strPublisher)
{
bool bDeleted = false;
if (m_pInterface != nullptr)
{
CComBSTR bstrPublisher = strPublisher.AllocSysString();
throw_if_fail(m_pInterface->DeletePublisher(bstrPublisher));
bDeleted = true;
}
return bDeleted;
}
They both work fine. The issue is that fact that the CPP method currently has no knowledge of the C# method having failed. Now, in this particular instance I know I could change the signature of the DLL method to return false for a exception failure occurring and examine that return value in the CPP file.
But, in other instances I am already using the return value and thus, it would seem for consistency to me, that I pass in a bool bExceptionRaised parameter instead to my methods in the DLL.
That way, I can test that value when the method seemed to complete and if it is false act accordingly.
At the moment my application doesn't realise that an exception occurred and that is confusion.
Can I assume that either of these methodologies are the simplest approach to what I am trying to detect?
Update
Based on the answer provided I have tried to follow this tutorial and I am getting confused. I have tried to follow it and I can't create a CLR DLL and build it that is a bridge to my C# DLL file.
Whilst I appreciate the answer I feel like it is breaking up everything I have worked on since the C# DLL already handles and logs it's exceptions. Whilst I would like to learn how to build this bridge for the future, I still think perhaps at the point in time just changing my signatures is sufficient. Either way, my attempt a basic build of a bridge is failing.
Use a C++/CLI wrapper for the access of the managed component.
With C++/CLI you can directly use the C# component can catch the managed exception and you can throw a native exception or even return true or false... whatever you want.
void DoManagedStuff(SOMEDATA somedata)
{
try
{
auto sm = ConvertToSomeDataToManaged(somedata);
CallManagedCode(sm);
}
catch (Exception^ e)
{
throw CMyNativeException();
}
}
I'm trying to get a node.js app to interact with a .NET SDK fingerprint reader called U.are.U. The SDK provides .dll (win32 and x64), Java and .NET libraries. I decided to use .NET for the simple of use, having all the interfaces ready to use and all.
So, the current problem I'm facing is how to call those .NET functions and still preserve the asynchronous nature of node.js. The application flow (on the .NET example) is pretty straight forward, 3 calls on the library, and the fingerprint is done.
private IEnumerable<Fmd> CaptureAndExtractFmd()
{
while (!reset)
{
DataResult<Fmd> resultConversion;
try
{
if (count >= 8)
{
SendMessage("Enrollment was unsuccessful. Please try again.");
count = 0;
break;
}
Fid fid = null;
if (!_sender.CaptureFinger(ref fid))
break;
if (fid == null)
continue;
count++;
resultConversion = FeatureExtraction.CreateFmdFromFid(fid, Constants.Formats.Fmd.ANSI);
SendMessage("A finger was captured. \r\nCount: " + (count));
if (resultConversion.ResultCode != Constants.ResultCode.DP_SUCCESS)
break;
}
catch (Exception)
{
break;
}
yield return resultConversion.Data;
}
}
How can I change it so it can be usable in node.js, instead of a .NET gui program?
It also need to be noted that the node.js isn't always going to call a function on the .NET program to receive a function. The identification part of the program happens asynchronously and is set off when someone places a finger on the fingerprint reader, that means that the node.js part have no idea when that is going to happen. So I cannot rely on asking data on the .NET part all the time, it must call callbacks on the node.js without having been asked. So basically, it's a bidirectional communication, not only on request, since requesting using a webserver would be much easier.
I've found a node.js library that can close the gap between .NET and node.js called edge.js would this be of any help?
Basically, edge.js can make it work, along with node-webkit (which I'll be shipping my app), I can call the node APIs directly in the page, so I can update the DOM depending on the result from the library. I need to be able to register an async task that CAN notify from inside the CLR to the node.js counterpart either by emitting an event or calling a callback!
According to the edge.js author it can be done easily https://github.com/tjanczuk/edge/issues/54#issuecomment-17967082 I just don't have enough .NET skills to do so (from a full fledged module) with all the callbacks.
Using this SDK's .NET library is not the appropriate solution for this problem.
Node.js itself is a C++ app, and trying to use a .NET library properly is just asking for a world of hurt, especially when the SDK also provides a native C/C++ library!
Of course, you can't just use the C++ library directly; you'll have to write a C++ wrapper. In the node world, these are known as addons. Writing an addon isn't exactly simple, but even someone with little C++ experience should be able to follow the examples in the documentation and get something working.
Getting a native addon built in Windows can also be a little tricky; here's some tips to help you get started.
Since the SDK you're using is behind a paywall, I can't provide any specific examples. However, I imagine your C++ wrapper object will expose a few methods, and you'll also write a JS wrapper around that to expose a clean API. For example:
var uareu = require('./uareu.node') // the native C++ addon dll
, events = require('events')
, util = require('util');
function FingerprintReader() {
events.EventEmitter.call(this); // initialize the EventEmitter
// do stuff with the native module
// whenever a finger is placed on the reader:
this.emit('finger', { id: idFromSdk });
}
util.inherits(FingerprintReader, events.EventEmitter); // we want this module
// to be an EventEmitter
module.exports = FingerprintReader; // export for require()ing in your app
Now your app can just:
var FingerprintReader = require('fingerprint')
, fp = new FingerprintReader();
fp.on('finger', function(d) {
// do something with `d.id`
});
This example obviously glosses over a lot, but should give you a good idea of what needs to happen on the JS end of things. As far as detecting when a finger is placed on the reader, again, I can't really say how you'll do that without access to the SDK. I'd bet that you'll end up polling somewhere. This should be done on a separate thread in your addon.
Bonus: going the native route means you'll probably also be compatible with the SDK's Linux version, so your app will also work on Linux!
After a long time since this question was posted, I can use edge.js easily to communicate IN and OUT my .NET UI (even control node.js within node-webkit from .NET UI), using node event emitter:
// demo basic code in node.js
var
edge = require('edge'),
Bridge = edge.func('../path/to/compiled.dll'),
callback,
ev = new require('events').EventEmitter();
ev.on('acquire', function(fingerdata){
console.log(fingerdata);
});
ev.on('error', function(){
});
callback = function(event, report){
// report the result of the event emitter back to .NET
// you can even pass the "report" to the event handler, so you can return anything you want back to .NET, not just a boolean
report(null, ev.emit(event.name, event.data));
//ev.emit(event.name, {data: event.data, report: report});
};
var bridge = Bridge(callback, true);
// calling bridge(null, true); "releases" my device, should be called on process.on('exit')
And now you can call in/out from .NET using events, instead of calling native code (that might not be thread safe)
namespace Bridge
{
public class Startup
{
public async Task<object> Invoke(Func<object, Task<object>>callback)
{
Bridge.Base.setCallback(callback);
MainForm mainForm = new Bridge.MainForm();
Task.Run(async () =>
{
Application.Run(mainForm);
});
return (Func<object, Task<object>>)(async (i) => { Bridge.Base.release(); return null; });
}
}
}
// inside Bridge.Base
static public void setCallback(Func<object, Task<object>> cb)
{
if (callback == null)
{
callback = cb;
}
}
static public async void Emit(string name, object data)
{
return await Task.Run(async () =>
{
return await callback(new {
name = name,
data = data
});
});
}
static public Func<object, Task<object>> callback = null;
can now call Emit('error', "My error") from anywhere my derived classes from Base, asynchronously. Just notice that I recently started dwelving in C#, and my code presented here might not be the best fit.
Interesting problem. Would it be possible to just drop the function that you care about into an ASHX file (custom HTTP handler) and then post to that from your node application? Depending on what you want to return you might have to do some serializing/deserializing, but this seems like it might be the easiest way to fire a piece of C# code from a Node app....
Microsoft has a pretty good set of tutorials on custom HTTP handlers that can be found here.
The basic ASHX skeleton is below:
<%# WebHandler Language="C#" Class="NodeHandler" %>
using System;
using System.Web;
public class NodeHandler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
//Handle fingerprint stuff!!!
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
public bool IsReusable {
get {
return false;
}
}
}
You would replace the contents of ProcessRequest with a modified version of your existing function.
I would create either self hosted WCF service ( ie windows service that has wcf endpoint) or use frameworks like OpenRasta or ServiceStack to replace WCF
In all three cases I would end up having json web service that return result of last call to CaptureAndExtractFmd
Then I would consume that service in node.js
If you need any further information with the way you decided to go, just create another question.
Sample code with WCF, C# part
[ServiceContract]
public interface IFingerprintContrat {
[OperationContract]
Fmd[] GetLastFeature();
}
public class FingerprintService {
Fmd[] GetLastFeature() {
return CaptureAndExtractFmd().ToArray()
}
}
using (ServiceHost host = new ServiceHost(typeof(FingerprintService), baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
Node.js part
var request = require("request");
request.get("baseaddress/GetLastFeature", function (err, res, body) {
if (!err) {
var resultsObj = JSON.parse(body);
console.log(resultsObj);
}
});
I have a project that makes extensive use of the GetGlobalResourceObject which is a member of the System.Web.UI class. It works fine providing english or french labels to the bilingual C#/ASP.NET application.
But....if the reference in the resource file is missing or malformed the application crashes
There are hundreds of calls like this
GetGlobalResourceObject("XXX.WebResource", "Remove")
Is there any way to encapsulate the GetGlobalResourceObject with an exception handler so that it returns null and logs it if there's a problem without adding a try/catch to each call?
I am new to C# so I don't know if I can override the GetGlobalResourceObject with my own class and then do a search and replace. Surely there is a better way.
Kevinsky
You can write your own version of GetGlobalResourceObject to embed the exception handling and logging in that:
public static Object MyGetGlobalResourceObject (string classKey,
string resourceKey)
{
try
{
return GetGlobalResourceObject (classKey, resourceKey);
}
catch (MissingManifestResourceException ex)
{
// log error
return null;
}
}
This code is provided as an starting point
You could even write it as an extension method on HttpContext.
You will have to do a global search and replace to call this rather than the base method, which isn't the most elegant solution, but it will work.