But generally, you just multiply a matrix with a local-space vector to get a global-space vector (assuming that matrix describes the relation between local and global space)

Usually you would do:

mat = bpy.context.object.matrix_world
vec = Vector((1,2,3))
vec_global = mat * vec

There is no real difference between a position and a direction. Both are 3D vectors, and any vector can act as a direction (except a null vector of course). A vector is generally normalized in order to be useful as a direction.

Vector to Matrix, that is kinda impossible. A 3x3 matrix is basically a set of 3 vectors, all perpendicular to each other, up / forward / right. So how would you construct a matrix from a single vector? You could, but you would have to assume that it is e.g. the forward vector, then calc a vector that points right relative to your vector and assume up to be 0,0,1 etc.

I posted something about such matrix construction recently, so you may wanna search the python forums.

Dear CoDEmanX:
Thanks for your guide every time. My best mentor.
finally. I use a data-function to rotate the mesh.

This is my test code.

import bpy
from mathutils import Matrix, Vector
C = bpy.context
#need two mesh, each one must have 1 selected point.
aobj = C.active_object
sobj = [i for i in C.selected_objects if i!= aobj][0]
selpnt = lambda x : [i.index for i in x.data.vertices if i.select][0]
apnt = selpnt(aobj)
spnt = selpnt(sobj)
amat = aobj.matrix_world.copy()
smat = sobj.matrix_world.copy()
anor = aobj.data.vertices[apnt].normal.copy().normalized()
snor = sobj.data.vertices[spnt].normal.copy().normalized()
#convert
amat = amat.inverted().transposed()
smat = smat.inverted().transposed()
anor = amat * anor
snor = smat * snor
angle = anor.angle(snor)
axis = snor.cross(anor).normalized()
rot = Matrix.Rotation(angle, 4, axis)
#
#my addon use "bpy.ops.transform.rotate" cause Blender 2.65+ crash.
#I guess I'll never have capability for figure out that.
#so. I changed to this way.
#But in this way.
#
sobj.data.transform(rot)
sobj.data.update()

Just to note; by using (mesh).data.transform(M), you are not transforming the object but rather all of the vertices in the object’s mesh data. Your object has not really rotated, its all of the vertices that have moved.

If you are looking to align the second object to a normal vector on the first object, you could just build a transformation matrix based on a position and normal that could then simply be applied as a target’s world matrix :

import bpy
from math import pi
from random import random as Rfloat
from random import randint as Rint
from mathutils import *
C = bpy.context
SC = bpy.context.scene
#static mesh
meshA = SC.objects['Mesh_A']
#align mesh
meshB = SC.objects['Mesh_B']
### Randomize mesh A transform
meshA.rotation_euler = ( Rfloat()*pi*2 , Rfloat()*pi*2 , Rfloat()*pi*2 )
'''
Scene.update() necessary here. Otherwise transform matrix will not
update until end of script.
'''
C.scene.update()
### Get vertice WS co and WS normal
vnum = Rint(0,len(meshA.data.vertices)-1) #get a random vert on target
WM = meshA.matrix_world #get target current world transform
TGTloc = WM * (meshA.data.vertices[vnum].co) #target WS vert coord
TGTnrml = WM.copy().to_3x3() * (meshA.data.vertices[vnum].normal) #targetWS normal vector
#set cursor location to vert WS pos
SC.cursor_location = TGTloc
#=== ALIGN OBJ 2 ===#
'''
Build basis vectors for transform matrix,
using target normal as Z. Normalize to negate
XY scaling.
'''
TM = Matrix.Identity(3)
TM.col[2] = TGTnrml #Z
TM.col[1] = TGTnrml.cross( (0,0,1) ) #Y
TM.col[0] = TM.col[1].cross(TGTnrml) #X
TM.normalize()
#to 4x4 and include translation vec
TM = TM.to_4x4()
TM.col[3] = TGTloc.to_4d()
#Apply transform
meshB.matrix_world = TM
C.scene.update()