[Translation] Using C # To write COM components

Source: Internet
Author: User

Source: Building COM objects in C #

 

Note:

I am a C #ProgramPersonnel, but once a requirement can only be written in C/C ++, the data exactly needs to be read is stored in dB (SQL ce V3, I don't know how to use C/C ++ (the key is to use oledb to access the database, which is really complicated), so I gave birth to the use of C # To write a COM component, the idea of calling with C/C ++. it is silly and naive. but it is also a way of thinking. If Ms provides C APIs, the problem will be much simpler. but the fact is, Ms's own. net CF uses C APIs, but exposes com APIs to users ..... OK.

 

Main content:

    • Use C # To create a simple COM component (through COM InterOP)
    • Use VC ++ to write a client to access the COM component. Use the TLB file on the client.

For ease of use, I imported northwind to sqlserver and tested myCodeI don't know what the sake of simplycity means. Is it because of diapers ....).

    • Modify the name of the machine in the COM component to your SQL Server machine name (more than 2005 requires the machine name \ Instance name)
    • Of course, I also created a user in it.ScottThe password isTigerTo connect to the database. You can select this user name or create a new one.

Part I: use C # To create a simple COM Component

COM object is a type of Library. COM component that will generate DLL files. In the vs environment, create COM component. Select ....

File-> New-> Project-> VisualC # projects-> class library.

CreateDatabase_comobjectClass Library Project.

Remember: To treat the C # object as a COM object, the following points are required...

    • The class must be public.
    • Attribute, method, and event must be public
    • Attributes and methods must be defined in interfaces.
    • The event must be in the event Interface

Not Defined in the interface, but is a public member in the implementation, is invisible to com, but to other. net program is visible. to expose attributes and methods to com, you must define them in the interface and mark them with dispid attributes to implement (......) in the class (.....). the members defined in the interface only use vtable (virtual function table ). to expose an event, you must define the member in the event interface and mark the dispid attribute. class does not need to implement this interface (???). Class can implement interfaces (a class can implement multiple interfaces, and only the first interface is the default Interface .). the attribute methods exposed to com are actually implemented in the class. they must be marked as public and comply with the definition in the interface. also, declare the events raised by the class here. they must be marked public and must match the declarations in the events interface. (These two sentences do not know the specific meaning, and there is no clue in the Code .)

Each interface must have a guid attribute (I called it an attribute or a custom attribute when I was in school, but I don't know what it is now...). You can useGuidgen.exeTo generate a guid value.

This interface looks like this:

 

 
[GUID ("694c1820-04b6-4988-928f-fd858b95c880")] public interface dbcom_interface {[dispid (1)] void Init (string userid, string password); [dispid (2)] bool executeselectcommand (string selcommand); [dispid (3)] bool nextrow (); [dispid (4)] void executenonselectcommand (string inscommand); [dispid (5)] string getcolumndata (int pos );}

 

  [GUID (  "  694c1820-04b6-4988-928f-fd858b95c880  "  )]
Public Interface Dbcom_interface
{
[Dispid ( 1 )]
Void Init ( String Userid, String Password );
[Dispid ( 2 )]
Bool Executeselectcommand ( String Selcommand );
[Dispid ( 3 )]
Bool Nextrow ();
[Dispid ( 4 )]
Void Executenonselectcommand ( String Inscommand );
[Dispid ( 5 )]
String Getcolumndata ( Int Pos );
}

Com event:

 

 
/// Events interface database_comobjectevents [GUID ("47c976e0-c208-4740-ac42-41212d3c34f0"), interfacetype (cominterfacetype. interfaceisidispatch)] public interface dbcom_events {}

 

Classes that implement interfaces:

 

 
[GUID ("identifier"), classinterface (classinterfacetype. None), comsourceinterfaces (typeof (dbcom_events)] public class dbcom_class: dbcom_interface {

Mark before the class:

 

Classinterface (classinterfacetype. None), comsourceinterfaces (typeof (dbcom_events)]

Classinterfacetype. none indicates that this class does not produce class interfaces. if no explicit interface is implemented, this class can only provide access to idispatch. the user expects to use the interface to export the explicitly implemented members of this class. therefore, you need to set classinterfaceattribute.

Comsourceinterfaces (typeof (dbcom_events)] The labeled class exposes the interface to the com event source. In our example, there is nothing to expose ..

The following is a complete COM Object:

 

Using system; using system. runtime. interopservices; using system. io; using system. text; using system. data. sqlclient; using system. windows. forms; namespace database_comobject {[GUID ("guid")] public interface dbcom_interface {[dispid (1)] void Init (string userid, string password); [dispid (2)] bool executeselectcommand (string selcommand); [dispid (3)] bool nextrow (); [dispid (4)] void executenonselectcommand (string inscommand); [dispid (5)] string getcolumndata (int pos);} // events interface database_comobjectevents [GUID ("identifier "), interfacetype (cominterfacetype. interfaceisidispatch)] public interface dbcom_events {} [GUID ("9e5e5fb2-219d-4ee7-ab27-e4dbed8e123e"), classinterface (classinterfacetype. none), comsourceinterfaces (typeof (dbcom _ Events)] public class dbcom_class: dbcom_interface {private sqlconnection myconnection = NULL; sqldatareader myreader = NULL; Public dbcom_class () {} public void Init (string userid, string password) {try {string myconnectstring = "User ID =" + userid + "; Password =" + password + "; database = northwind; server = Skywalker; Connect timeout = 30 "; myconnection = new sqlconnection (myconnectstring); myconnecti On. open (); // MessageBox. show ("connected");} catch (exception e) {MessageBox. show (E. message) ;}} public bool executeselectcommand (string selcommand) {If (myreader! = NULL) myreader. close (); sqlcommand mycommand = new sqlcommand (selcommand); mycommand. connection = myconnection; mycommand. executenonquery (); myreader = mycommand. executereader (); Return true;} public bool nextrow () {If (! Myreader. read () {myreader. close (); Return false;} return true;} Public String getcolumndata (int pos) {object OBJ = myreader. getvalue (POS); If (OBJ = NULL) Return ""; return obj. tostring ();} public void executenonselectcommand (string inscommand) {sqlcommand mycommand = new sqlcommand (inscommand, myconnection); int donews = mycommand. executenonquery ();}}}

 

 

Before compiling COM components, you must register them in COM InterOP.

Choose Solution Explorer> Properties> Configuration> build> Expand the output section> Register for com InterOP to true.

(This is not the case in vs 2008. Right-click the project and choose Properties> build> bottom output> Register for com InterOP to true ).

It indicates that I want to export the managed program to a COM object, and the COM object can interact with our hosting program.

To export the comobject, you can use sn.exe to generate a strongname:

Sn-K database_com_key.snk

In the assemblyinfo. CS file, modify:

[Assembly: assemblykeyfile ("database_com_key.snk")]

Compile this object. a tlb file is generated. You can use this file to allow both the managed code and native code to access your COM object.

Part II: Use VC ++ to create a client to access this COM Object

I have accessed the COM Object in VC ++ 6.0 and VC ++. net.

Create a simple project# Import directiveImport Type Library.

 

Create an instance that can only point to the interface and execute the export functions to ensure that coinitialize () is executed during program loading ().

 

 
Coinitialize (null); database_comobject: dbcom_interfaceptr P (_ uuidof (database_comobject: dbcom_class); db_com_ptr = P; db_com_ptr-> Init ("Scott", "Tiger ");

 

The following code queries the customer table using a customer ID:

 

 
Char cmd [1024]; sprintf (CMD, "select companyName, contactname, contacttitle, address from MERs where customerid = '% S'", m_id); const char * P; bool ret = db_com_ptr-> executeselectcommand (CMD); If (! Db_com_ptr-> nextrow () return; _ bstr_t mdata = db_com_ptr-> getcolumndata (3); P = mdata; m_address = (cstring) P;

 

PS:

The translation is complete... the English is not good. Some sentences cannot understand the meaning. If the English is good, we recommend that you read e directly.

I can only say that I am miserable. I had a good idea at the beginning. Unfortunately, under. Net CF, C # is not supported to write a COM component.

My mantra is:. Net CF has no other advantages except slowness.

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.