Passing STL parameters and vector objects as DLL parameters in DLL

Source: Internet
Author: User

 

STL cross-platform calls may encounter many exceptions. You can try it. STL uses the template generation. When we use the template, every EXE and DLL generates their own code in the compiler, causing the static members used by the template to be not synchronized, the following is a detailed explanation of data transmission problems.

Cause analysis:
One sentence ----- if any STL class uses static variables (whether directly or indirectly), do not write code that accesses it across execution units. Unless you are sure that the two dynamic libraries use the same STL implementation, for example, both use the STL of the same version of VC, and the compilation options are the same. We strongly recommend that you do not pass STL containers in the dynamic library interface !!

STL may not be passed between DLL files, but you must thoroughly understand its internal implementation and understand why something went wrong.
Microsoft's explanation:

Http://support.microsoft.com/default.aspx? SCID = kb % 3ben-us % 3b172396

Solutions provided by Microsoft:

Http://support.microsoft.com/default.aspx? SCID = kb % 3ben-us % 3b168958

1. Microsoft's explanation:
Most classes in the C ++ standard library use static variables directly or indirectly. Because these variables are extended by templates, each executable image (usually the .dllor. EXE file) has a static data member of its own and given class. When a class method that needs to access these static members is executed, it uses the static member variable in "the executable image where the code of this method is currently located. Because the static data members of the two executable images are not synchronized, this behavior may cause access violations, or the data may seem lost or damaged.

It may not be easy to understand. For example, if Class A <t> has a static variable M_s, then 1.exe uses 2. when a <int> object provided in DLL is created by the template extension mechanism, 1.exe and 2. the dll contains its own static variable A <int>. m_s.
For example, from 2. DLL to obtain a Class A <int> Of the upload object A, so you can directly access a in 1.exe. m_s, the actual access is the corresponding copy in 1.exe (the correct situation should be that access 2. a. m_s ). This may lead to abnormal situations, such as illegal access, unchanged data, and incorrect changes to data that should not be changed.

Original article:
Most classes in the Standard C ++ libraries use static data members directly or indirectly. since these classes are generated through template instantiation, each executable image (usually with DLL or EXE file name extensions) will contain its own copy
Of the static data member for a given class. when a method of the class that requires the static data member is executed, it uses the static data member in the executable image in which the method code resides. since the static data members in the executable
Images are not in sync, this action cocould result in an access violation or data may appear to be lost or upted.

1. Ensure that the resource allocation/deletion operations are equal and in the same execution unit;
For example, you can hide these operations (including constructor/destructor, memory redistribution when some containers are automatically resized {This requires special attention}) into interface functions. In other words, try not to output STL objects directly from the DLL. If you must output the STL object, add a layer of packaging to it, and then output the packaging interface instead of the original interface.

2. Ensure that all execution units use the same version of STL Runtime Library.
For example, the release library or the debug library are all used. Otherwise, the memory layout of the STL class extended by the two execution units may be different.

Remember that if any STL class uses static variables (whether directly or indirectly), do not write code that accesses it across execution units.

Solution:
1. A solution that can be considered
For example, if there are two dynamic libraries L1 and L2, and L2 needs to modify a map in L1, then I set the following interface in L1:
Int modify_map (INT key, int new_value );
If you need to specify "A Map", you can consider implementing a method similar to a handle. For example, you can pass a DWORD
However, this DWORD contains an address.

Then, modify_map can be implemented as follows:
Int modify_map (DWORD map_handle, int key, int new_value)
{
STD: Map <int, int> & themap = * (STD: Map <int, int> *) map_handle;
Themap [Key] = new_value;
}

The value of map_handle is first "told" L2 by L1:
DWORD get_map_handle ();

L2 can be called like this:
Dword h = get_map_handle ();
Modify_map (H, 1, 2 );

2. add an additional layer to solve the problem. Therefore, you need to wrap your map inside the DLL, instead of making it appear in the interface. The simpler the dynamic library interface, the better. It is difficult to transmit complicated things as a famous saying :)

 

In dynamic connection library development, pay special attention to the issue of memory allocation and release. If you do not pay attention to it, it is very likely to cause memory leakage and thus access errors. For example, a dll contains the following code:

Extent "C" _ declspec (dllexport)
Void extractfilename (const STD: string & Path //! <Input path and filename.
, STD: string & fname //! <Extracted filename with extension.
)
{
STD: String: size_type startpos = path. find_last_of ('\\');
Fname. Assign (path. Begin () startpos 1, path. End ());
}

Use the STL object STD: string in the DLL and change the content of STD: String in it, that is, the memory redistribution problem occurs, if this function is called in EXE, memory access problems may occur. Mainly because the DLL and exe memory allocation methods are different, the allocated memory in the DLL cannot be correctly released in the exe.

The solution is as follows:
Under normal circumstances: To build a DLL, you must follow the principle of who allocates the DLL and who releases it. For example, the com solution (using reference count) and the object creation (QueryInterface) and released within the COM component. In a pure C environment, similar solutions can be easily implemented.

In the case of applying STL, it is difficult to use the above solution to solve the problem. Therefore, there are two ways to solve this problem:
1. Write your own memory distributor to replace the default one in STL.
2. Use stlport to replace the standard library of the system.

In fact, the above problems have been solved in vc7 and later versions. Note that multi-threaded DLL libraries must be used for DLL projects and called projects so that memory access will not occur.

 

 

A strange problem: An error occurred while using STD: string as the parameter result in DLL. STL
During this time, some functions in the project are encapsulated into a dynamic library, and some types of STL are used as parameters when the dynamic library interface is required.

For example, String, vector, list. But when using the interface.

  1. Class exportclass
  2. {
  3. Bool dll_funcation (string & Str );
  4. };

Copy code

// The above class is just a form, and the specific content is not written. This class is exported.

When I use this library, write the code as follows:

  1. String STR = "":
  2. Exportclass TMP;
  3. TMP. dll_function (STR );

Copy code

This function can be successfully called. however, this array will be included in the function. if the string is too long, an error occurs. function call is successful, but once the STR resource needs to be released, the resource cannot be released, prompting that the wrong memory space has been released.

The code for this function is removed.

STR = "qadasdasdsafsafas ";

An error is returned.

If it is changed to a short string, no error will occur.
At this time, we can only try to think that the space for strings is too small.

In the end, I changed it to this, and the error disappears. I hope the error is caused by this.

  1. String STR = "":
  2. Str. Resize (1000 );
  3. Exportclass TMP;
  4. TMP. dll_function (STR );

 

When I write a program today, I want to pass a parameter to the DLL of a module. because the number of parameters is variable, the vector <string> type is designed, however, after the parameters in the EXE are passed to the function in the DLL during the debugging process, the vector becomes empty. After being changed to the reference type, the vector becomes very large and meaningless.

There are two ways to solve this problem:

1. Pass the vector pointer

2. Pass the const vector <type>.

The reason is:

The reason is that when the vector is transferred between the EXE and DLL, because the data may be inserted to the vector in the DLL, and the memory is allocated in the DLL, the EXE cannot know how to release the memory, this causes problems. After being changed to the const type, the compiler will know that the DLL will not change the vector, so as to avoid errors.

Or you can say this is "cross-DLL problem. "(This problem crops up when an object is created using new in one dynamically linked library (DLL) but is deleted in a different DLL.

For STL, these problems often exist when used in DLL, which need to be paid attention when using STL on the network.

**************************************** **************************************** *******************************

Reference http://www.hellocpp.net/Articles/Article/714.aspx

When a template encounters a dynamic link, it is often a nightmare.

Now let's talk about some of the problems I have encountered. The problems are mainly focused on memory allocation.

1>

For STL, it is inevitable that STL will be used when you write your own templates. all STL code is in the header file. indicates the memory allocation code. the memory allocation code is determined only when the CPP containing it is compiled. consider: When you declare a vector <>. and pass the vector <> to the Code in a DLL for use. after use, it is released in your program. if you insert something into the vector in the DLL. in this case, the memory allocation code generated by insert is DLL. you don't know what the dll Memory Allocation is. where is the allocation.
At this time. releasing the promotion action is not in the DLL ..... at the same time. you cannot even ensure that the STL version used by the guy who compiled the DLL is exactly the same as that used by you...>

In this case, the program crash is justified ....

Countermeasure: Never upload your STL container. The template container is passed between the DLL. Remember that the string is also ....

2>

You declare a vector container in a class of DLL without explicitly writing the constructor and destructor of this class. Then the problem arises again.

Your class must have a function to operate the vector. these functions allow vecoter <> to generate code. these codes are consistent in this DLL. but don't forget. you didn't write the Destructor ...... if someone else declares such a class at this time. then, the function of this class is called to operate the vector (of course, the user does not know when to operate the vector ). after the class is used up. class is released. the compiler generates an destructor code for it ...... okay. this Code is not in the DLL .... the thing is the same as that in 1> .... crash ...... (It may be accompanied by confusion .....)

Countermeasure: remember every class in the DLL, even if the Destructor is empty. write it to CPP. nothing is written. It's terrible ..... at the same time, it is necessary to write any function related to memory operations. CPP...

3>

The above two problems seem to be relatively easy-as long as the code is written into CPP, do not use the STL container to transmit it.

The third question is much more troublesome.

If you write a template by yourself, this template uses the STL container ..........

What should you do at this time?

Obviously, you cannot write all the functions related to memory allocation to. cpp. The template code must be included in the header file .....

Countermeasure: the basic method to solve this problem is to create an STL memory distributor and forcibly place the memory allocation related to this template into one. in CPP. at this time, the CPP will fix the memory allocation code in one place: Or DLL. or in exe...

There are still many problems with the use of templates and dynamic link libraries. Please pay attention to this trap.

**************************************** **************************************** **************************************** ***

Microsoft's explanation of such problems:

You may experience an access violation when you access an STL object through a pointer or reference in a different DLL or EXE

Http://support.microsoft.com/default.aspx? SCID = KB; en-US; q172396

How to export an instantiation of a standard template library (STL) class and a class that contains a data member that is an STL object

Http://support.microsoft.com/default.aspx? SCID = KB; en-US; q168958

 

 

 

Summary:

The string parameter uses char *, and the vector uses char **,

The principle of who applies for and who releases the dynamic memory should be kept in mind.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.