I have one C# DLL and one Visual Basic 6 DLL.
In C# there is a field x with data type Decimal. In VB6 there is a field y with data type Currency.
What would be the best way to pass x to y and back?
Currently I convert the fields to Double, but I am not sure if there are rounding implications.
Update 1:
Based on the helpful advice this is what my code looks now:
public void FromVbToNet(long vb6curr)
{
decimal value = vb6curr / 10000;
}
Problem is, when I try to call this from VB6 via interop, I get a compile error:
"Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic"
So how do I declare vb6curr? String, Object, Dynamic?
Update 2:
In case anyone needs this for reference, after further reading I came up with the following solution:
[return: MarshalAs(UnmanagedType.Currency)]
public decimal GetDecimalFromNetDll()
{
decimal value = ... // Read from database
return value;
}
public void SetDecimalInNetDll([MarshalAs(UnmanagedType.Currency)] decimal value)
{
// Save to database
}
I call these from my unmanaged code in VB6 with a Currency parameter and everything seems to work so far.
A VB6 Currency
data type is stored as a 64 bit integer, implicitly scaled by 10,000
. Armed with that knowledge it is straightforward to convert between that type and .net Decimal
.
On the VB6 side you pass the data as Currency
. On the C# side you pass it as long
. Then on the C# side you scale by 10,000
to convert between your decimal
value and the long
value.
For example when you have a VB6 Currency
value held in a C# long you convert to decimal
like this:
long vb6curr = ...;
decimal value = vb6curr / 10000;
In the other direction it would be:
decimal value = ...;
long vb6curr = Convert.ToInt64(value*10000);
After some reading I came up with this solution (see also under Update 2).
I had to marshal the Decimal type in .Net to the Currency type in the unmanaged VB6 code and vice versa.
[return: MarshalAs(UnmanagedType.Currency)]
public decimal GetDecimalFromNetDll()
{
decimal value = ... // Read from database
return value;
}
public void SetDecimalInNetDll([MarshalAs(UnmanagedType.Currency)] decimal value)
{
// Save to database
}
For detailed information see: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute%28v=vs.110%29.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With