Managed dll import complaining about string marshalling
Hi folks,
I am using a Managed dll to use Measuring Computing's DAQ, a piece of hardware that lets me do fancy analogue I/O. I'm able to import the dll, instantiate the class, and even access fields, but when I try to call a method, I get:
NotImplementedException: string marshalling conversion 34 not implemented.
I guess my first question is: Is it OK to use a managed dll that calls native dlls? I've run into a problem in the past where I couldn't have one dll access another, but they were both c++.
The second question is: could I get this exception by simply not having the right header or required native dll accessible?
Any guidance would be much appreciated!
Alex
Answer by clausmeister · Mar 26, 2016 at 12:03 AM
Hi Alex,
I just ran into the same issue when trying to use a managegd DAQ library (MccDaq/Meilhaus) inside of Unity. Have you made any progress on this issue?
Kind regards, claus
Answer by AlexMiller12 · Mar 26, 2016 at 01:25 AM
I never got the managed dll to work. I don't remember why, it was either because Unity doesn't like even managed dlls calling other dlls or something to do with the compiler they used. I ended up using the native 64 bit dll. This is the class I used to wrap it:
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
// This class wraps up the MCDAQ dll. This is the library that lets us set the
// voltage of our device
//TODO error checking for cb calls
public class MCDAQ
{
//------------------------------------------------------------------------CONSTANTS:
private const string LOG_TAG = "MCDAQ";
private const bool VERBOSE = false;
// Types of configuration
private static int GLOBALINFO = 1;
private static int BOARDINFO = 2;
// Types of board configuration info
private static int BIRANGE = 6; // Switch selectable range
private static int BICLOCK = 5; // Switch selectable range
// Available ranges
private static int BIP10VOLTS = 1; // -10 to +10 Volts
private static int BIP5VOLTS = 0; // -5 to +5 Volts
private static int UNI10VOLTS = 100; // 0 to +10 Volts
// Types of error reporting
private static int DONTPRINT = 0;
private static int PRINTALL = 3;
// Types of error handling
private static int DONTSTOP = 0;
private static int STOPALL = 2;
private static float CURRENT_REVISION_NUMBER = 6.51f;
private static int BOARD_NUMBER = 0;
private static int RANGE = BIP10VOLTS;
private static int CHANNEL = 0;
//---------------------------------------------------------EXTERNAL METHODS IMPORTS:
[DllImport( "cbw64" )]
private static extern int cbDeclareRevision( ref float revisionNumber );
[DllImport( "cbw64" )]
private static extern int cbAOut( int boardNumber,
int channel,
int gain,
ushort dataValue );
[DllImport( "cbw64" )]
private static extern int cbErrHandling( int reporting, int handling );
[DllImport( "cbw64" )]
private static extern int cbFlashLED( int boardNumber );
[DllImport( "cbw64" )]
private static extern int cbFromEngUnits( int boardNumber,
int range,
float engineeringUnits,
out ushort dataValue );
[DllImport( "cbw64" )]
private static extern int cbGetConfig( int infoType,
int boardNumber,
int deviceNumber,
int configurationItem,
out int configurationValue );
[DllImport( "cbw64" )]
private static extern int cbSetConfig( int infoType,
int boardNumber,
int deviceNumber,
int configurationItem,
int configurationValue );
[DllImport( "cbw64" )]
private static extern int cbVOut( int boardNumber,
int channel,
int range,
float dataValue,
int options );
//---------------------------------------------------------------------------FIELDS:
private static bool isInitialized;
//--------------------------------------------------------------------------METHODS:
public static void flashLED()
{
cbFlashLED( BOARD_NUMBER );
}
public static void init()
{
// Declare the current software version
float revisionNum = CURRENT_REVISION_NUMBER;
cbDeclareRevision( ref revisionNum );
// Specify internal error handling
cbErrHandling( PRINTALL, DONTSTOP );
isInitialized = true;
}
public static void writeVolts( float volts )
{
ushort dataValue;
if( VERBOSE )
{
Utility.print(LOG_TAG, "Writing Volts: " + volts);
}
// Go from pos/neg volts to unsigned int
cbFromEngUnits( BOARD_NUMBER, RANGE, volts, out dataValue );
// Send signal to actuate
cbAOut( BOARD_NUMBER, CHANNEL, RANGE, dataValue );
}
}
Thank you sir. Yes I think that this is the problem with quite some managed .Net libraries out there that were specifically designed to work with one platform in $$anonymous$$d, using other dependencies (quite often Windows.Forms) native to that platform. $$anonymous$$ono with its multiplatform credo does not like that so much i guess.
Thanks for the wrapper code.
hi ! I am struggling with the same kind of issue, using mccdaq dll to send digital byte. once you wrap in the class, could you explain how to access a method from mccdaq ? should i implement the method myself in the wrapper class like flashled ?
should i instantiate the class ? eerm... i'm a bit lost there!
thanks a lot in advance and thank you already for this part of code :)
Do you happen to know where to find the manual for the 64 bit dll ? Or a list of all the exports or something.
Your answer
Follow this Question
Related Questions
DLL Properties grayed out (unselectable), unable to exclude plugin from platforms 0 Answers
Unity Editor crashes when loading managed Plug-in (external DLL) 1 Answer
DllNotFoundException, C++ dll used with an assembly, not possible? 0 Answers
using Google.Protobuf & ZeroMQ 0 Answers
dllnotfoundexception : zip.dll 0 Answers