what is the java DataInputStream readFully method equivalent in C# BinaryReader?
What is the java DataInputStream mark and reset methods equivalent in C# BinaryReader or Stream?
see BinaryReader.Read(byte[], int, int)
There is no object that have this behavior in .NET, you should implement it by yourself.
Related
This question already has answers here:
How to pass a Delphi Stream to a c/c++ DLL
(2 answers)
Closed 1 year ago.
Streams are very mysterious for me, so please be patient and friendly :) I am trying to create a Stream in Delphi, which I can pass to C# as a parameter. Does anybody know how to do that?
Note that I am able to call the C# function from my Delphi project like down below. I've followed this tutorial to create a DLL from my C# project and to implement the DLL in Delphi.
procedure TForm1.Button1Click(Sender: TObject);
var
Stream : TStream;
Baz : TBaz;
begin
Baz := TBaz.Create(Self);
// Create Stream & call Bar() with the created Stream as parameter
Baz.Bar(?param?);
end;
My C# project looks like this:
public class Baz
{
public void Bar(?param?)
{
// Get stream here
}
}
I highly appreciate any help, sheers!
Edit:
The stream should be a file stream
Both Delphi and C# have support for IStream interface for interoperability purposes. You can wrap any stream with TStreamAdapter. If you are constructing the stream on Delphi side you need to make sure that wrapped stream instance will live longer than IStream wrapper or you need to pass ownership of the stream to the adapter.
uses
Winapi.ActiveX,
System.Classes;
var
FileStream: TFileStream;
Stream: IStream;
begin
FileStream := TFileStream.Create(...);
try
Stream := TStreamAdapter.Create(FileStream);
// use stream
Baz.Bar(Stream);
finally
Stream := nil;
FileStream.Free;
end;
end;
or
var
FileStream: TFileStream;
Stream: IStream;
begin
FileStream := TFileStream.Create(...);
Stream := TStreamAdapter.Create(FileStream, soOwned);
// use stream
Baz.Bar(Stream);
end;
Documentation:
System.Classes.TStreamAdapter
IStream interface
Does a wrapper class for a COM interop IStream already exist?
Of course, you can always pass filename to C# and construct the stream on C# side.
Streams are implementation-specific to each compiler, so you can't pass a (native) Delphi TStream to C# and expect it to work over there. Likewise a C# Stream is not compatible with a (native) Delphi TStream, so you can't go the other way as well.
It may be possible (using a lot of dirty hacks) to do some form of inter-operability between C# classes and Delphi classes, but quite frankly, it'll be a lot of work for very little benefit, in particular (no insult intended) for your current level of experience (as you consider streams "mysterious").
If it is a file you are trying to pass over, pass the file name instead and let the C# side allocate a C# stream to access it.
Edit: You can use the IStream interface to wrap the (native) Delphi TStream instance and pass this interface to C#, which then should be able to access the (native) Delphi TStream from the (managed) C# code. See Dalija Prasnikar's answer.
I am trying to read a binary file in C# which has been written actually using CArchive. I have done most of the part but stuck in reading an object. Instead of writing bool, int, double object has been written into binary.
http://msdn.microsoft.com/en-us/library/3bfsbt0t(v=vs.110).aspx
So original code is something like this.
MyClass myObject;
if (archive.IsStoring()
archive << myObject;
else
archive >> myOjbect;
So question is how can I translate this piece of code in C#.
void Read(BinaryReader reader)
{
// Read MyClass object here.
}
You'll need to create a comparable C# object (you might want to use C++/CLI) and construct it from the file.
It would help if you specified what myObject is.
I'm working on some software that is written in native C++ with a managed C++ wrapper and the user interface in C#. I need to pass some information from the native code all the way up to the interface. The best way I can think to pass my information is in a list of tuples. I understand that in the native C++ I need to use a list<tuple<..>> and that works fine. What I want to do now, is take that output in the wrapper, and return a List<Tuple<..>> which is the System::Collections::Generic::List and System::Tuple instead of the stl ones from the native. I know the lists are very different syntactically but that shouldn't be the issue. In the C# code a List<Tuple<..>> is accepted by the compiler but in the managed C++ code it is not. Am I doing this wrong/am I using the wrong data types? Any help would be awesome!
Try something like this:
using namespace System::Collections::Generic;
// A List<Tuple<int, float>> in managed C++
public ref class TupleTest
{
public:
static List<Tuple<int, float>^>^ GetTuple() {
List<Tuple<int, float>^>^ ret = gcnew List<Tuple<int,float>^>();
Tuple<int,float>^ t = gcnew Tuple<int,float>(5, 2.6);
ret->Add(t);
return ret;
}
};
Note: you could use Int32 and Single (or Double) instead of int/float if you like.
EDIT: Notice the ^ operators. Those denote C++/CLI reference types. You'll be using them a lot! (It's kinda like * for pointers in regular C++, but means GC'ed reference type)
I am new in C# programming and trying to call wrap functions that is in C++.
In C++ I have a function of the following prototype
string* swap(string* ptr1, string*ptr2){
//swap the array of string
return ptr2;
}
How do I wrap this function into C# (ideally using SWIG, but not necessary)?
I had the same question for Java.
For Java, I did not find anything pre-packaged and trivial to use. I had to define my own typemaps.
In case you don't get any better answers for C#, you could start with the SWIG/C++ code described at SWIG: How to wrap std::string& (std::string passed by reference) .
You would need to replace references to Java types, JNI methods (those that include a reference to "jenv"), and "JavaThrowException."
These files from SWIG might also provide some relevant example code for C#:
swig/Lib/csharp/std_string.i
swig/Lib/csharp/typemaps.i
I tried different things but i'm getting mad with Interop.
(here the word string is not referred to a variabile type but "a collection of char"):
I have an unmanaged C++ function, defined in a dll, that i'm trying to access from C#, this function has a string parameter and a string return value like this:
string myFunction(string inputString)
{
}
What should be string in C++ side? and C# one? and what parameters need DllImport for this?
What I've found to work best is to be more explicit about what's going on here. Having a string as return type is probably not recommended in this situation.
A common approach is to have the C++ side be passed the buffer and buffer size. If it's not big enough for what GetString has to put in it, the bufferSize variable is modified to indicate what an appropriate size would be. The calling program (C#) would then increase the size of the buffer to the appropriate size.
If this is your exported dll function (C++):
extern "C" __declspec void GetString( char* buffer, int* bufferSize );
Matching C# would be the following:
void GetString( StringBuilder buffer, ref int bufferSize );
So to use this in C# you would then do something like the following:
int bufferSize = 512;
StringBuilder buffer = new StringBuilder( bufferSize );
GetString( buffer, ref bufferSize );
The only good way that I know of doing this is to write a .NET C++ wrapper class using Managed C++ Extensions, and within the .NET C++ object call your native C++ code. There are functions in the managed extensions to convert a System.String to a char* or any other type of unmanaged string.
Basically you create a .NET class using C++ and expose it from an assembly, and internally to that assembly you can call your native C++ code. The other way is to add a pure C function to your C++ code using P/Invoke and then call your C code from C# and have your C function call your C++ code. This will work, but I tend to try to use managed code as much as possible.
The biggest problem with passing strings from C++ back to C# is the memory allocation. The GC should be able to know how to cleanup the memory allocated for this string. Since C# has extensive COm interop support, it does know about COM BSTRs and how to allocate and deallocate these. Thus the easiest way to do this would be to use BSTR on the C++ side and string on the C# side.
Note, using BSTRs does not imply that your function has to be expose through COM.
The "string" return value is the problem. The P/Invoke marshaller is going to call CoTaskMemFree() on the pointer you return. That's not going to work well unless you used CoTaskMemAlloc() in your C/C++ code to allocate the string buffer. Which is a fairly unusual thing to do.
The best solution is to allow the caller of your code to pass a pointer to a buffer and the buffer length to you as arguments. That way all memory allocation happens on one side. Scott showed you how to do this.
I had to convert a unicode C# string to a multibyte representation in order to convert to char* in c++ (this is partial one way solution)
I found the following very useful
string st;
IntPtr stPtr = Marshal.StringToHGlobalAnsi(st);
// Do your thing in C++
Marshal.FreeHGlobal(stPtr);
This may be inefficient and not in C# manner, I'm new to C#.