It's possibille for a dll file to remember a value? - dll

I have this code:
static int nr = 0;
public static void MyMethod() {
if (nr == 0) nr = 1;
}
I build the project and I get the dll file. I use the dll file for the first time and I know for sure that the nr is 0 and nr will get the "1" value. I destroy the AppDomain and I loose that value.
My question: I have the dll file.
I use the dll file for the first time and my code generate a value.
Can I maintain that value or any value in my code without coding it or without saving in a file or in a registry?

if u want to maintain that value only on that particular page then store in a global variable or in ViewState intrinsic object. For User level store in Session.

Related

I have a DEVINST, I need the Device Path

I'm trying to open a WinUSB device that is part of a composite device. I have located the correct child device using cfgmgr32, and have its DEVINST number. In order to open it with WinUSB, I need to first call CreateFile, for which I need the Device Path.
The Device Path looks like:
\\\\?\\usb#vid_9999&pid_0102#3555303335351909000b0#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
How can I obtain the Device Path?
I recommend looking at the get_filename_from_devinst_and_guid function which is part of libusbp.
The basic outline is:
Make sure you know the device interface GUID you are looking for. That is the thing in brackets at the end of the filename you provided. This usually comes from the INF file that sets up WinUSB, though it can also come from MS OS descriptors on the device. You can find it in the registry. You have to pack it into a Win32 API GUID struct.
Call SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); to get a list of all the present (connected) devices supporting that device interface GUID.
Use SetupDiEnumDeviceInfo to iterate through the list until you find the item that matches the DEVINST you already found.
Use SetupDiEnumDeviceInterfaces to get the list of interfaces for that item. There should only be one entry because you already specified the device interface GUID you are interested in.
Use SetupDiGetDeviceInterfaceDetail to get SP_DEVICE_INTERFACE_DETAIL_DATA_A data structure.
The filename you are looking for is in the DevicePath member of that structure.
This function returns a list of NULL-terminated Device Paths (that's what we get from CM_Get_Device_Interface_List)
You need to pass it the DEVINST, and the wanted interface GUID.
Since both the DEVINST and interface GUID are specified, it is highly likely that CM_Get_Device_Interface_List will return a single Device Path for that interface, but technically you should be prepared to get more than one result.
I used this function successfully in production code for getting the Device Interface of a USB HUB (GUID_CLASS_USBHUB): I used the resulting Device Path with CreateFile and opened it succesfully.
It is responsibility of the caller to delete[] the returned list if the function returns successfully (return code 0)
int GetDevInstInterfaces(DEVINST dev, LPGUID interfaceGUID, wchar_t**outIfaces, ULONG* outIfacesLen)
{
CONFIGRET cres;
if (!outIfaces)
return -1;
if (!outIfacesLen)
return -2;
// Get System Device ID
WCHAR sysDeviceID[256];
cres = CM_Get_Device_ID(dev, sysDeviceID, sizeof(sysDeviceID) / sizeof(sysDeviceID[0]), 0);
if (cres != CR_SUCCESS)
return -11;
// Get list size
ULONG ifaceListSize = 0;
cres = CM_Get_Device_Interface_List_Size(&ifaceListSize, interfaceGUID, sysDeviceID, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cres != CR_SUCCESS)
return -12;
// Allocate memory for the list
wchar_t* ifaceList = new wchar_t[ifaceListSize];
// Populate the list
cres = CM_Get_Device_Interface_List(interfaceGUID, sysDeviceID, ifaceList, ifaceListSize, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cres != CR_SUCCESS) {
delete[] ifaceList;
return -13;
}
// Return list
*outIfaces = ifaceList;
*outIfacesLen = ifaceListSize;
return 0;
}

C++/CLI method calls native method to modify int - need pin_ptr?

I have a C++/CLI method, ManagedMethod, with one output argument that will be modified by a native method as such:
// file: test.cpp
#pragma unmanaged
void NativeMethod(int& n)
{
n = 123;
}
#pragma managed
void ManagedMethod([System::Runtime::InteropServices::Out] int% n)
{
pin_ptr<int> pinned = &n;
NativeMethod(*pinned);
}
void main()
{
int n = 0;
ManagedMethod(n);
// n is now modified
}
Once ManagedMethod returns, the value of n has been modified as I would expect. So far, the only way I've been able to get this to compile is to use a pin_ptr inside ManagedMethod, so is pinning in fact the correct/only way to do this? Or is there a more elegant way of passing n to NativeMethod?
Yes, this is the correct way to do it. Very highly optimized inside the CLR, the variable gets the [pinned] attribute so the CLR knows that it stores an interior pointer to an object that should not be moved. Distinct from GCHandle::Alloc(), pin_ptr<> can do it without creating another handle. It is reported in the table that the jitter generates when it compiles the method, the GC uses that table to know where to look for object roots.
Which only ever matters when a garbage collection occurs at the exact same time that NativeMethod() is running. Doesn't happen very often in practice, you'd have to use threads in the program. YMMV.
There is another way to do it, doesn't require pinning but requires a wee bit more machine code:
void ManagedMethod(int% n)
{
int copy = n;
NativeMethod(copy);
n = copy;
}
Which works because local variables have stack storage and thus won't be moved by the garbage collector. Does not win any elegance points for style but what I normally use myself, estimating the side-effects of pinning is not that easy. But, really, don't fear pin_ptr<>.

Confusion about the Argument< T > and Variable< T > in .NET 4.0 Workflow Foundation

I am using Windows Workflow Foundation in .NET 4.0. Below is some syntax/semantic confusion I have.
I have 2 equivalent way to declare an Assign activity to assign a value to a workflow variable (varIsFreeShipping).
(1) Using XAML in the designer.
(2) Using code.
But in approach 2, the it seems I am creating a new OutArgument< Boolean > and assign value to it, not to the original Variable< Boolean> varIsFreeShipping. And OutArgument and Variable are totally different types.
So how could the value assigned to this new Argument finally reach the original Variable?
This pattern seems common in WF 4.0. Could anybody shed some light on this?
Thanks!
As a matter of fact, the second (2) method can be written just as:
Then = new Assign<bool>
{
To = varIsFreeShipping,
Value = true
}
This all works because OutArgument<T> can be initialized through a Variable<T> using an implicit operator.
In your first (1) assign, using the editor, that's what's happening behind the scene; the variable is being implicitly converted from Variable to OutArgument.
WF4 uses alot of implicit operators mainly on Activity<T> from/to Variable<T>, OutArgument<T> from/to Variable<T>, etc. If you look at it, they all represent a piece of data (already evaluated or not), that is located somewhere. It's exactly the same as in C#, for example:
public int SomeMethod(int a)
{
var b = a;
return a;
}
You can assign an argument to a variable, but you can also return that same variable as an out argument. That's what you're doing with that Assign<T> activity (using the variable varIsFreeShipping as the activity's out argument).
This answers your question?

writing module to .bc bitcode file

i've assumed that dumping a .bc file from a module was a trivial operation, but now,
first time i have to actually do it from code, for the life of me i
can't find one missing step in the process:
static void WriteModule ( const Module * M, BitstreamWriter & Stream )
http://llvm.org/docs/doxygen/html/BitcodeWriter_8cpp.html#a828cec7a8fed9d232556420efef7ae89
to write that module, first i need a BistreamWriter
BitstreamWriter::BitstreamWriter (SmallVectorImpl< char > &O)
http://llvm.org/docs/doxygen/html/classllvm_1_1BitstreamWriter.html
and for a BitstreamWriter i need a SmallVectorImpl. But, what next?
Should i write the content of the SmallVectorImpl byte by byte on a
file handler myself? is there a llvm api for this? do i need something
else?
The WriteModule function is static within lib/Bitcode/Writer/BitcodeWriter.cpp, which means it's not there for outside consumption (you can't even access it).
The same file has another function, however, called WriteBitcodeToFile, with this interface:
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out);
I can't imagine a more convenient interface. The header file declaring it is ./include/llvm/Bitcode/ReaderWriter.h, by the way.
I use following code :
std::error_code EC;
llvm::raw_fd_ostream OS("module", EC, llvm::sys::fs::F_None);
WriteBitcodeToFile(pBiFModule, OS);
OS.flush();
and then disassemble using llvm-dis.

DllImport and return parameters

I am working on hardware testing. Our test framework is written in C# but we are using native dlls to talk to hardware.
Say we have a C++ method:
unsigned char someMethod(unsigned long * nativeStatus)
which in turns executes an embedded command and returns a status when command completes.
To use it we create a wrapper
[DllImport(#"native.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
internal static extern Byte someMethod(ref UInt32 managedStatus)
This works fine. But there is a scenario when someMethod call does not actually execute a command but just adds it to a sequence. Then the sequence can be executed by sending a special command say ExecuteSequence. As the sequence is being executed C++ code updates the nativeStatus by just copying the data into the memory referenced by the nativeStatus pointer. As the sequence completes ExecuteSequence method returns. At this time I am sure that all data (nativeStatus in this case) is updated. Will my managedStatus be correctly updated as well? I heard that in this case managedStatus and nativeStatus are not pointing to the same memory. Marshaler just returns a copy of nativeState after call completes. If not what is the solution? Do I need to use the unsave keyword and put my code creating and executing a sequence in the fixed{} block?
[DllImport(#"native.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
internal static unsave extern Byte someMethod(UInt32 * managedStatus)
So what you need is a variable location of which will not change over a timespan.
Yes, you can use fixed{} for that.
Alternatively, you can pin that variable:
private uint g_Pinnable = 0;
...
var gc = System.Runtime.InteropServices.GCHandle.Alloc(g_Pinnable, System.Runtime.InteropServices.GCHandleType.Pinned);
try
{
// Pass 'ref g_Pinnable' to API
// Then execute the sequence.
}
finally
{
gc.Free(); // Reference to g_Pinnable may be invalid after this point
}